@tearleads/client-sdk 0.1.62 → 0.1.63
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/client/organizations/currentPrincipalMutations.js +5 -5
- package/client/organizations/currentPrincipalMutations.js.map +1 -1
- package/client/organizations/organizationDataUsage.js +1 -1
- package/client/organizations/organizationDataUsage.js.map +1 -1
- package/client/organizations/organizationGroupHistory.js +1 -1
- package/client/organizations/organizationGroupHistory.js.map +1 -1
- package/client/organizations/organizationGroupNameHydration.js +3 -3
- package/client/organizations/organizationGroupNameHydration.js.map +1 -1
- package/client/organizations/organizationHistory.js +2 -2
- package/client/organizations/organizationHistory.js.map +1 -1
- package/client/organizations/organizationReadModels.js +1 -1
- package/client/organizations/organizationReadModels.js.map +1 -1
- package/client/organizations/principalContainerMutations.js +1 -1
- package/client/organizations/principalContainerMutations.js.map +1 -1
- package/client/organizations/principalMutationRecovery.js.map +1 -1
- package/client/organizations/principalMutations.js +5 -5
- package/client/organizations/principalMutations.js.map +1 -1
- package/client/runtime/principalMutationApi.d.ts +1 -1
- package/client/runtime/principalMutationApi.js +2 -2
- package/client/runtime/principalMutationApi.js.map +1 -1
- package/client/runtime/principalMutationDispatch.js +1 -1
- package/client/runtime/principalMutationDispatch.js.map +1 -1
- package/client/session/index.js +1 -1
- package/client/session/index.js.map +1 -1
- package/client/session/sessionOrganizationCreation.js +1 -1
- package/client/session/sessionOrganizationCreation.js.map +1 -1
- package/client/session/sessionPurgeRecovery.js +2 -2
- package/client/session/sessionPurgeRecovery.js.map +1 -1
- package/package.json +1 -1
- package/stores/documents/documentStore/attachmentHydrationCommit.js +1 -1
- package/stores/documents/documentStore/attachmentHydrationCommit.js.map +1 -1
- package/stores/documents/documentStore/attachmentUploadAttempt.js +1 -1
- package/stores/documents/documentStore/syncRemoteSignals.js +1 -1
- package/stores/documents/documentStore/syncRemoteSignals.js.map +1 -1
- package/stores/documents/documentStore/syncShared.js +1 -1
- package/stores/documents/documentStore/syncShared.js.map +1 -1
- package/workflows/blobs/detach.js +1 -1
- package/workflows/blobs/detach.js.map +1 -1
- package/workflows/blobs/{blobChunkDecryption.js → hydration/blobChunkDecryption.js} +3 -3
- package/workflows/blobs/hydration/blobChunkDecryption.js.map +1 -0
- package/workflows/blobs/{decrypt.d.ts → hydration/decrypt.d.ts} +2 -2
- package/workflows/blobs/{decrypt.js → hydration/decrypt.js} +14 -14
- package/workflows/blobs/hydration/decrypt.js.map +1 -0
- package/workflows/blobs/{hydrate.d.ts → hydration/hydrate.d.ts} +7 -7
- package/workflows/blobs/{hydrate.js → hydration/hydrate.js} +5 -5
- package/workflows/blobs/hydration/hydrate.js.map +1 -0
- package/workflows/blobs/{hydrationResults.js → hydration/hydrationResults.js} +2 -2
- package/workflows/blobs/hydration/hydrationResults.js.map +1 -0
- package/workflows/blobs/index.d.ts +3 -3
- package/workflows/blobs/index.js +3 -3
- package/workflows/blobs/index.js.map +1 -1
- package/workflows/blobs/{automaticMultipartUpload.js → upload/automaticMultipartUpload.js} +1 -1
- package/workflows/blobs/upload/automaticMultipartUpload.js.map +1 -0
- package/workflows/blobs/{upload.d.ts → upload/index.d.ts} +2 -2
- package/workflows/blobs/{upload.js → upload/index.js} +14 -14
- package/workflows/blobs/upload/index.js.map +1 -0
- package/workflows/blobs/{multipartFirstParts.js → upload/multipartFirstParts.js} +4 -4
- package/workflows/blobs/upload/multipartFirstParts.js.map +1 -0
- package/workflows/blobs/{multipartStageFailures.js → upload/multipartStageFailures.js} +1 -1
- package/workflows/blobs/upload/multipartStageFailures.js.map +1 -0
- package/workflows/blobs/upload/multipartStageResolution.js.map +1 -0
- package/workflows/blobs/{multipartUpload.js → upload/multipartUpload.js} +3 -3
- package/workflows/blobs/upload/multipartUpload.js.map +1 -0
- package/workflows/blobs/{attachmentBindingVerification.js → verification/attachmentBindingVerification.js} +3 -3
- package/workflows/blobs/verification/attachmentBindingVerification.js.map +1 -0
- package/workflows/blobs/{attachmentDecryptor.js → verification/attachmentDecryptor.js} +3 -3
- package/workflows/blobs/verification/attachmentDecryptor.js.map +1 -0
- package/workflows/blobs/{attachmentKeyAuthenticator.js → verification/attachmentKeyAuthenticator.js} +5 -5
- package/workflows/blobs/verification/attachmentKeyAuthenticator.js.map +1 -0
- package/workflows/blobs/{retainedAttachmentVerification.js → verification/retainedAttachmentVerification.js} +5 -5
- package/workflows/blobs/verification/retainedAttachmentVerification.js.map +1 -0
- package/workflows/blobs/{verifiedWrapScope.js → verification/verifiedWrapScope.js} +2 -2
- package/workflows/blobs/verification/verifiedWrapScope.js.map +1 -0
- package/workflows/blobs/{writerProjection.js → verification/writerProjection.js} +3 -3
- package/workflows/blobs/verification/writerProjection.js.map +1 -0
- package/workflows/container-contents/container-state/purgeTree.js.map +1 -1
- package/workflows/container-contents/container-state/purgeTreeContainerDeletion.js.map +1 -1
- package/workflows/container-contents/container-state/remote.js +1 -1
- package/workflows/container-contents/container-state/remote.js.map +1 -1
- package/workflows/container-contents/documentLinks/index.d.ts +1 -1
- package/workflows/container-contents/documentLinks/index.js.map +1 -1
- package/workflows/container-contents/info/containerInfo.d.ts +1 -1
- package/workflows/container-contents/metadata/metadataIncomingUpdateIsolation.js +1 -1
- package/workflows/container-contents/metadata/metadataIncomingUpdateIsolation.js.map +1 -1
- package/workflows/container-contents/remoteHydration/destinationRootReload.js +1 -1
- package/workflows/container-contents/remoteHydration/destinationRootReload.js.map +1 -1
- package/workflows/container-contents/remoteHydration/verifiedDestination.js +1 -1
- package/workflows/container-contents/remoteHydration/verifiedDestination.js.map +1 -1
- package/workflows/container-contents/tombstones/documentPurge.d.ts +1 -1
- package/workflows/container-contents/tombstones/documentPurge.js.map +1 -1
- package/workflows/containers/child/currentShareGrantMutation.js +5 -5
- package/workflows/containers/child/currentShareGrantMutation.js.map +1 -1
- package/workflows/containers/child/currentSharePrincipalPolicy.js +5 -5
- package/workflows/containers/child/currentSharePrincipalPolicy.js.map +1 -1
- package/workflows/containers/child/runtimeCurrentGroupShare.js +1 -1
- package/workflows/containers/child/runtimeCurrentGroupShare.js.map +1 -1
- package/workflows/containers/child/share.d.ts +1 -1
- package/workflows/containers/child/share.js +4 -4
- package/workflows/containers/child/share.js.map +1 -1
- package/workflows/containers/child/sharePrincipalPolicy.d.ts +1 -1
- package/workflows/containers/child/sharePrincipalPolicy.js +2 -2
- package/workflows/containers/child/sharePrincipalPolicy.js.map +1 -1
- package/workflows/documents/{attachmentPersistence.d.ts → attachments/attachmentPersistence.d.ts} +2 -2
- package/workflows/documents/attachments/attachmentPersistence.js.map +1 -0
- package/workflows/documents/{blobMutationLock.d.ts → attachments/blobMutationLock.d.ts} +1 -1
- package/workflows/documents/{blobMutationLock.js → attachments/blobMutationLock.js} +1 -1
- package/workflows/documents/attachments/blobMutationLock.js.map +1 -0
- package/workflows/documents/attachments/orphanBlobReclaimState.js.map +1 -0
- package/workflows/documents/{orphanBlobReclaims.d.ts → attachments/orphanBlobReclaims.d.ts} +2 -2
- package/workflows/documents/{orphanBlobReclaims.js → attachments/orphanBlobReclaims.js} +3 -3
- package/workflows/documents/attachments/orphanBlobReclaims.js.map +1 -0
- package/workflows/documents/authorAccessFailure.js.map +1 -1
- package/workflows/documents/{createAdoption.js → create/createAdoption.js} +5 -5
- package/workflows/documents/create/createAdoption.js.map +1 -0
- package/workflows/documents/{createProjection.d.ts → create/createProjection.d.ts} +1 -1
- package/workflows/documents/{createProjectionFetch.d.ts → create/createProjectionFetch.d.ts} +2 -2
- package/workflows/documents/create/createProjectionFetch.js.map +1 -0
- package/workflows/documents/{createResponse.js → create/createResponse.js} +5 -5
- package/workflows/documents/create/createResponse.js.map +1 -0
- package/workflows/documents/{documentCreationPersistence.js → create/documentCreationPersistence.js} +2 -2
- package/workflows/documents/create/documentCreationPersistence.js.map +1 -0
- package/workflows/documents/{create.d.ts → create/index.d.ts} +4 -4
- package/workflows/documents/{create.js → create/index.js} +10 -10
- package/workflows/documents/create/index.js.map +1 -0
- package/workflows/documents/documentMutationCommit.js +1 -1
- package/workflows/documents/documentMutationCommit.js.map +1 -1
- package/workflows/documents/index.d.ts +17 -17
- package/workflows/documents/index.js +14 -14
- package/workflows/documents/index.js.map +1 -1
- package/workflows/documents/{linkSet.d.ts → linkSet/index.d.ts} +5 -5
- package/workflows/documents/{linkSet.js → linkSet/index.js} +12 -12
- package/workflows/documents/linkSet/index.js.map +1 -0
- package/workflows/documents/{linkSetAuthority.js → linkSet/linkSetAuthority.js} +6 -6
- package/workflows/documents/linkSet/linkSetAuthority.js.map +1 -0
- package/workflows/documents/{linkSetBlobRewraps.js → linkSet/linkSetBlobRewraps.js} +13 -13
- package/workflows/documents/linkSet/linkSetBlobRewraps.js.map +1 -0
- package/workflows/documents/{linkSetProjectionSeed.js → linkSet/linkSetProjectionSeed.js} +2 -2
- package/workflows/documents/linkSet/linkSetProjectionSeed.js.map +1 -0
- package/workflows/documents/{linkSetRemote.d.ts → linkSet/linkSetRemote.d.ts} +4 -4
- package/workflows/documents/{linkSetRemote.js → linkSet/linkSetRemote.js} +6 -6
- package/workflows/documents/linkSet/linkSetRemote.js.map +1 -0
- package/workflows/documents/{purge.d.ts → purge/index.d.ts} +5 -5
- package/workflows/documents/{purge.js → purge/index.js} +9 -9
- package/workflows/documents/purge/index.js.map +1 -0
- package/workflows/documents/{persistedDocumentRemoval.d.ts → purge/persistedDocumentRemoval.d.ts} +3 -3
- package/workflows/documents/{persistedDocumentRemoval.js → purge/persistedDocumentRemoval.js} +4 -4
- package/workflows/documents/purge/persistedDocumentRemoval.js.map +1 -0
- package/workflows/documents/{subtreePurgeScope.d.ts → purge/subtreePurgeScope.d.ts} +1 -1
- package/workflows/documents/{subtreePurgeScope.js → purge/subtreePurgeScope.js} +2 -2
- package/workflows/documents/purge/subtreePurgeScope.js.map +1 -0
- package/workflows/documents/rotationBaseline.js +1 -1
- package/workflows/documents/rotationBaseline.js.map +1 -1
- package/workflows/documents/{sync.d.ts → sync/index.d.ts} +1 -1
- package/workflows/documents/{sync.js → sync/index.js} +11 -11
- package/workflows/documents/sync/index.js.map +1 -0
- package/workflows/documents/{initialSync.js → sync/initialSync.js} +5 -5
- package/workflows/documents/sync/initialSync.js.map +1 -0
- package/workflows/documents/{readOnlyProjectionFailure.js → sync/readOnlyProjectionFailure.js} +5 -5
- package/workflows/documents/sync/readOnlyProjectionFailure.js.map +1 -0
- package/workflows/documents/{readOnlySync.d.ts → sync/readOnlySync.d.ts} +9 -9
- package/workflows/documents/{readOnlySync.js → sync/readOnlySync.js} +11 -11
- package/workflows/documents/sync/readOnlySync.js.map +1 -0
- package/workflows/documents/sync/reportDocumentSyncQuarantine.js.map +1 -0
- package/workflows/documents/{syncAttemptPlanning.js → sync/syncAttemptPlanning.js} +9 -9
- package/workflows/documents/sync/syncAttemptPlanning.js.map +1 -0
- package/workflows/documents/{syncAttemptState.d.ts → sync/syncAttemptState.d.ts} +5 -5
- package/workflows/documents/sync/syncAttemptState.js.map +1 -0
- package/workflows/documents/{syncLane.d.ts → sync/syncLane.d.ts} +3 -3
- package/workflows/documents/{syncLane.js → sync/syncLane.js} +2 -2
- package/workflows/documents/sync/syncLane.js.map +1 -0
- package/workflows/documents/{syncResponseResult.js → sync/syncResponseResult.js} +9 -9
- package/workflows/documents/sync/syncResponseResult.js.map +1 -0
- package/workflows/documents/{syncSubmittedResult.js → sync/syncSubmittedResult.js} +6 -6
- package/workflows/documents/sync/syncSubmittedResult.js.map +1 -0
- package/workflows/documents/{syncTrace.js → sync/syncTrace.js} +1 -1
- package/workflows/documents/{syncFailures.js → syncFailures/index.js} +5 -5
- package/workflows/documents/syncFailures/index.js.map +1 -0
- package/workflows/documents/{syncAbandon.js → syncFailures/syncAbandon.js} +1 -1
- package/workflows/documents/syncFailures/syncAbandon.js.map +1 -0
- package/workflows/documents/{syncFailureClassification.d.ts → syncFailures/syncFailureClassification.d.ts} +2 -2
- package/workflows/documents/{syncFailureClassification.js → syncFailures/syncFailureClassification.js} +6 -6
- package/workflows/documents/syncFailures/syncFailureClassification.js.map +1 -0
- package/workflows/documents/{syncPolicyRepair.js → syncFailures/syncPolicyRepair.js} +3 -3
- package/workflows/documents/syncFailures/syncPolicyRepair.js.map +1 -0
- package/workflows/documents/syncFailures/syncRepairAbandon.js.map +1 -0
- package/workflows/documents/{syncRepairAccess.js → syncFailures/syncRepairAccess.js} +2 -2
- package/workflows/documents/syncFailures/syncRepairAccess.js.map +1 -0
- package/workflows/documents/{syncContentKeys.d.ts → syncPlan/syncContentKeys.d.ts} +4 -4
- package/workflows/documents/{syncContentKeys.js → syncPlan/syncContentKeys.js} +8 -8
- package/workflows/documents/syncPlan/syncContentKeys.js.map +1 -0
- package/workflows/documents/{syncPlanIdentity.js → syncPlan/syncPlanIdentity.js} +3 -3
- package/workflows/documents/syncPlan/syncPlanIdentity.js.map +1 -0
- package/workflows/documents/{syncPlanMaterial.js → syncPlan/syncPlanMaterial.js} +9 -9
- package/workflows/documents/syncPlan/syncPlanMaterial.js.map +1 -0
- package/workflows/documents/syncPlan/syncPlanProjection.js.map +1 -0
- package/workflows/documents/{syncPlanRequestBounds.js → syncPlan/syncPlanRequestBounds.js} +1 -1
- package/workflows/documents/syncPlan/syncPlanRequestBounds.js.map +1 -0
- package/workflows/documents/{syncAutomaticContainerRekeys.js → syncRekeys/syncAutomaticContainerRekeys.js} +10 -10
- package/workflows/documents/syncRekeys/syncAutomaticContainerRekeys.js.map +1 -0
- package/workflows/documents/{syncContainerRekeyPreparation.js → syncRekeys/syncContainerRekeyPreparation.js} +11 -11
- package/workflows/documents/syncRekeys/syncContainerRekeyPreparation.js.map +1 -0
- package/workflows/documents/{syncContainerRekeyProjection.js → syncRekeys/syncContainerRekeyProjection.js} +2 -2
- package/workflows/documents/syncRekeys/syncContainerRekeyProjection.js.map +1 -0
- package/workflows/documents/{syncContainerRekeys.js → syncRekeys/syncContainerRekeys.js} +3 -3
- package/workflows/documents/syncRekeys/syncContainerRekeys.js.map +1 -0
- package/workflows/documents/{syncRecoveryRekey.d.ts → syncRekeys/syncRecoveryRekey.d.ts} +4 -4
- package/workflows/documents/{syncRecoveryRekey.js → syncRekeys/syncRecoveryRekey.js} +4 -4
- package/workflows/documents/syncRekeys/syncRecoveryRekey.js.map +1 -0
- package/workflows/documents/{syncRekeyCommit.js → syncRekeys/syncRekeyCommit.js} +1 -1
- package/workflows/organizations/{currentGroupMetadataAuthority.js → groupMetadata/currentGroupMetadataAuthority.js} +5 -5
- package/workflows/organizations/groupMetadata/currentGroupMetadataAuthority.js.map +1 -0
- package/workflows/organizations/{groupMetadataAccess.d.ts → groupMetadata/groupMetadataAccess.d.ts} +5 -5
- package/workflows/organizations/{groupMetadataAccess.js → groupMetadata/groupMetadataAccess.js} +6 -6
- package/workflows/organizations/groupMetadata/groupMetadataAccess.js.map +1 -0
- package/workflows/organizations/{groupMetadataBinding.js → groupMetadata/groupMetadataBinding.js} +1 -1
- package/workflows/organizations/groupMetadata/groupMetadataBinding.js.map +1 -0
- package/workflows/organizations/{groupMetadataContainerAuthority.js → groupMetadata/groupMetadataContainerAuthority.js} +6 -6
- package/workflows/organizations/groupMetadata/groupMetadataContainerAuthority.js.map +1 -0
- package/workflows/organizations/{groupMetadataErrors.js → groupMetadata/groupMetadataErrors.js} +1 -1
- package/workflows/organizations/{groupMetadataRootBinding.js → groupMetadata/groupMetadataRootBinding.js} +3 -3
- package/workflows/organizations/groupMetadata/groupMetadataRootBinding.js.map +1 -0
- package/workflows/organizations/{groupMetadataRuntime.js → groupMetadata/groupMetadataRuntime.js} +4 -4
- package/workflows/organizations/groupMetadata/groupMetadataRuntime.js.map +1 -0
- package/workflows/organizations/{runtimeGroupMetadataAuthority.js → groupMetadata/runtimeGroupMetadataAuthority.js} +2 -2
- package/workflows/organizations/groupMetadata/runtimeGroupMetadataAuthority.js.map +1 -0
- package/workflows/organizations/{currentOrganizationGroupNames.js → groupNames/currentOrganizationGroupNames.js} +8 -8
- package/workflows/organizations/groupNames/currentOrganizationGroupNames.js.map +1 -0
- package/workflows/organizations/{groupMembershipName.d.ts → groupNames/groupMembershipName.d.ts} +3 -3
- package/workflows/organizations/{groupMembershipName.js → groupNames/groupMembershipName.js} +2 -2
- package/workflows/organizations/groupNames/groupMembershipName.js.map +1 -0
- package/workflows/organizations/{groupNameUniqueness.js → groupNames/groupNameUniqueness.js} +11 -11
- package/workflows/organizations/groupNames/groupNameUniqueness.js.map +1 -0
- package/workflows/organizations/{organizationGroupNamePolicies.js → groupNames/organizationGroupNamePolicies.js} +5 -5
- package/workflows/organizations/groupNames/organizationGroupNamePolicies.js.map +1 -0
- package/workflows/organizations/{organizationGroupNames.js → groupNames/organizationGroupNames.js} +1 -1
- package/workflows/organizations/groupNames/organizationGroupNames.js.map +1 -0
- package/workflows/organizations/{commitCurrentGroupPolicyMutation.js → groupPolicy/commitCurrentGroupPolicyMutation.js} +4 -4
- package/workflows/organizations/groupPolicy/commitCurrentGroupPolicyMutation.js.map +1 -0
- package/workflows/organizations/{currentGroupPolicyMutationContext.js → groupPolicy/currentGroupPolicyMutationContext.js} +7 -7
- package/workflows/organizations/groupPolicy/currentGroupPolicyMutationContext.js.map +1 -0
- package/workflows/organizations/{currentPolicyMutationAcknowledgement.js → groupPolicy/currentPolicyMutationAcknowledgement.js} +3 -3
- package/workflows/organizations/groupPolicy/currentPolicyMutationAcknowledgement.js.map +1 -0
- package/workflows/organizations/{groupPolicyMutationAcknowledgement.js → groupPolicy/groupPolicyMutationAcknowledgement.js} +4 -4
- package/workflows/organizations/groupPolicy/groupPolicyMutationAcknowledgement.js.map +1 -0
- package/workflows/organizations/{groupPolicyMutationContext.d.ts → groupPolicy/groupPolicyMutationContext.d.ts} +8 -8
- package/workflows/organizations/{groupPolicyMutationContext.js → groupPolicy/groupPolicyMutationContext.js} +5 -5
- package/workflows/organizations/groupPolicy/groupPolicyMutationContext.js.map +1 -0
- package/workflows/organizations/{groupPolicyMutationEvidence.d.ts → groupPolicy/groupPolicyMutationEvidence.d.ts} +4 -4
- package/workflows/organizations/{groupPolicyMutationEvidence.js → groupPolicy/groupPolicyMutationEvidence.js} +3 -3
- package/workflows/organizations/groupPolicy/groupPolicyMutationEvidence.js.map +1 -0
- package/workflows/organizations/{groupPolicyMutationHead.js → groupPolicy/groupPolicyMutationHead.js} +1 -1
- package/workflows/organizations/{groupPolicyRequests.js → groupPolicy/groupPolicyRequests.js} +5 -5
- package/workflows/organizations/groupPolicy/groupPolicyRequests.js.map +1 -0
- package/workflows/organizations/{groupPolicyVerification.js → groupPolicy/groupPolicyVerification.js} +5 -5
- package/workflows/organizations/groupPolicy/groupPolicyVerification.js.map +1 -0
- package/workflows/organizations/{submitGroupPolicyCommit.d.ts → groupPolicy/submitGroupPolicyCommit.d.ts} +3 -3
- package/workflows/organizations/{submitGroupPolicyCommit.js → groupPolicy/submitGroupPolicyCommit.js} +1 -1
- package/workflows/organizations/groupPolicy/submitGroupPolicyCommit.js.map +1 -0
- package/workflows/organizations/{createCurrentOrganizationGroup.js → groups/createCurrentOrganizationGroup.js} +9 -9
- package/workflows/organizations/groups/createCurrentOrganizationGroup.js.map +1 -0
- package/workflows/organizations/{deleteCurrentOrganizationGroup.js → groups/deleteCurrentOrganizationGroup.js} +2 -2
- package/workflows/organizations/groups/deleteCurrentOrganizationGroup.js.map +1 -0
- package/workflows/organizations/{deleteOrganizationGroup.d.ts → groups/deleteOrganizationGroup.d.ts} +6 -6
- package/workflows/organizations/{deleteOrganizationGroup.js → groups/deleteOrganizationGroup.js} +6 -6
- package/workflows/organizations/groups/deleteOrganizationGroup.js.map +1 -0
- package/workflows/organizations/{groupCreation.d.ts → groups/groupCreation.d.ts} +7 -7
- package/workflows/organizations/{groupCreation.js → groups/groupCreation.js} +4 -4
- package/workflows/organizations/groups/groupCreation.js.map +1 -0
- package/workflows/organizations/{organizationGroupDirectory.js → groups/organizationGroupDirectory.js} +10 -10
- package/workflows/organizations/groups/organizationGroupDirectory.js.map +1 -0
- package/workflows/organizations/index.d.ts +13 -13
- package/workflows/organizations/index.js +12 -12
- package/workflows/organizations/index.js.map +1 -1
- package/workflows/organizations/policyHistory/groupPolicyHistoryPage.js.map +1 -0
- package/workflows/organizations/{loadPolicyHistoryDetails.js → policyHistory/loadPolicyHistoryDetails.js} +5 -5
- package/workflows/organizations/policyHistory/loadPolicyHistoryDetails.js.map +1 -0
- package/workflows/organizations/{organizationPolicyHistoryDetails.js → policyHistory/organizationPolicyHistoryDetails.js} +2 -2
- package/workflows/organizations/policyHistory/organizationPolicyHistoryDetails.js.map +1 -0
- package/workflows/organizations/{organizationPolicyHistoryVerification.js → policyHistory/organizationPolicyHistoryVerification.js} +2 -2
- package/workflows/organizations/policyHistory/organizationPolicyHistoryVerification.js.map +1 -0
- package/workflows/organizations/{policyHistoryAccessDenial.js → policyHistory/policyHistoryAccessDenial.js} +3 -3
- package/workflows/organizations/policyHistory/policyHistoryAccessDenial.js.map +1 -0
- package/workflows/organizations/{policyHistoryCache.js → policyHistory/policyHistoryCache.js} +1 -1
- package/workflows/organizations/policyHistory/policyHistoryCache.js.map +1 -0
- package/workflows/organizations/{policyHistoryReadModel.d.ts → policyHistory/policyHistoryReadModel.d.ts} +1 -1
- package/workflows/organizations/{policyHistoryTypes.d.ts → policyHistory/policyHistoryTypes.d.ts} +1 -1
- package/workflows/organizations/{acknowledgedDirectoryBindings.js → principalMutations/acknowledgedDirectoryBindings.js} +2 -2
- package/workflows/organizations/principalMutations/acknowledgedDirectoryBindings.js.map +1 -0
- package/workflows/organizations/{currentGroupMutationReferences.js → principalMutations/currentGroupMutationReferences.js} +2 -2
- package/workflows/organizations/principalMutations/currentGroupMutationReferences.js.map +1 -0
- package/workflows/organizations/{currentOrganizationMutationAuthority.js → principalMutations/currentOrganizationMutationAuthority.js} +3 -3
- package/workflows/organizations/principalMutations/currentOrganizationMutationAuthority.js.map +1 -0
- package/workflows/organizations/{currentOrganizationMutationRetention.js → principalMutations/currentOrganizationMutationRetention.js} +4 -4
- package/workflows/organizations/principalMutations/currentOrganizationMutationRetention.js.map +1 -0
- package/workflows/organizations/{currentPrincipalMutationLease.js → principalMutations/currentPrincipalMutationLease.js} +6 -6
- package/workflows/organizations/principalMutations/currentPrincipalMutationLease.js.map +1 -0
- package/workflows/organizations/{principalMutationJournalManagement.d.ts → principalMutations/principalMutationJournalManagement.d.ts} +1 -1
- package/workflows/organizations/{principalMutationJournalManagement.js → principalMutations/principalMutationJournalManagement.js} +7 -7
- package/workflows/organizations/principalMutations/principalMutationJournalManagement.js.map +1 -0
- package/workflows/organizations/{principalMutationJournalSession.d.ts → principalMutations/principalMutationJournalSession.d.ts} +4 -4
- package/workflows/organizations/{principalMutationJournalSession.js → principalMutations/principalMutationJournalSession.js} +4 -4
- package/workflows/organizations/principalMutations/principalMutationJournalSession.js.map +1 -0
- package/workflows/organizations/{principalMutationReceipt.js → principalMutations/principalMutationReceipt.js} +3 -3
- package/workflows/organizations/principalMutations/principalMutationReceipt.js.map +1 -0
- package/workflows/organizations/{principalOperationReceipt.d.ts → principalMutations/principalOperationReceipt.d.ts} +2 -2
- package/workflows/organizations/{principalOperationReceipt.js → principalMutations/principalOperationReceipt.js} +3 -3
- package/workflows/organizations/principalMutations/principalOperationReceipt.js.map +1 -0
- package/workflows/organizations/principalMutations/retainAcknowledgedPrincipalCurrents.d.ts +6 -0
- package/workflows/organizations/{retainAcknowledgedPrincipalCurrents.js → principalMutations/retainAcknowledgedPrincipalCurrents.js} +4 -4
- package/workflows/organizations/principalMutations/retainAcknowledgedPrincipalCurrents.js.map +1 -0
- package/workflows/organizations/{runtimeCurrentGroupMutation.js → principalMutations/runtimeCurrentGroupMutation.js} +5 -5
- package/workflows/organizations/principalMutations/runtimeCurrentGroupMutation.js.map +1 -0
- package/workflows/organizations/{runtimeCurrentOrganizationMutation.js → principalMutations/runtimeCurrentOrganizationMutation.js} +2 -2
- package/workflows/organizations/principalMutations/runtimeCurrentOrganizationMutation.js.map +1 -0
- package/workflows/organizations/{principalPolicy.d.ts → principalPolicy/index.d.ts} +8 -8
- package/workflows/organizations/{principalPolicy.js → principalPolicy/index.js} +9 -9
- package/workflows/organizations/principalPolicy/index.js.map +1 -0
- package/workflows/organizations/{principalPolicyApi.d.ts → principalPolicy/principalPolicyApi.d.ts} +4 -4
- package/workflows/organizations/principalPolicy/principalPolicyApi.js.map +1 -0
- package/workflows/organizations/{principalPolicyReceiptArtifacts.js → principalPolicy/principalPolicyReceiptArtifacts.js} +2 -2
- package/workflows/organizations/principalPolicy/principalPolicyReceiptArtifacts.js.map +1 -0
- package/workflows/organizations/{principalPolicyRecipients.js → principalPolicy/principalPolicyRecipients.js} +2 -2
- package/workflows/organizations/principalPolicy/principalPolicyRecipients.js.map +1 -0
- package/workflows/organizations/{principalPolicyRequest.d.ts → principalPolicy/principalPolicyRequest.d.ts} +3 -3
- package/workflows/organizations/{principalPolicyRequest.js → principalPolicy/principalPolicyRequest.js} +2 -2
- package/workflows/organizations/{createOrganization.d.ts → provisioning/createOrganization.d.ts} +7 -7
- package/workflows/organizations/{createOrganization.js → provisioning/createOrganization.js} +3 -3
- package/workflows/organizations/provisioning/createOrganization.js.map +1 -0
- package/workflows/organizations/{organizationProvisioningAttempt.d.ts → provisioning/organizationProvisioningAttempt.d.ts} +3 -3
- package/workflows/organizations/{organizationProvisioningAttempt.js → provisioning/organizationProvisioningAttempt.js} +6 -6
- package/workflows/organizations/provisioning/organizationProvisioningAttempt.js.map +1 -0
- package/workflows/organizations/{organizationReplacementVerification.js → provisioning/organizationReplacementVerification.js} +2 -2
- package/workflows/organizations/provisioning/organizationReplacementVerification.js.map +1 -0
- package/workflows/organizations/{dataUsageReadModel.d.ts → readModel/dataUsageReadModel.d.ts} +3 -3
- package/workflows/organizations/{dataUsageReadModel.js → readModel/dataUsageReadModel.js} +2 -2
- package/workflows/organizations/readModel/dataUsageReadModel.js.map +1 -0
- package/workflows/organizations/{readModel.d.ts → readModel/index.d.ts} +5 -5
- package/workflows/organizations/{readModel.js → readModel/index.js} +2 -2
- package/workflows/organizations/readModel/index.js.map +1 -0
- package/workflows/organizations/{listLocalOrganizations.d.ts → readModel/listLocalOrganizations.d.ts} +1 -1
- package/workflows/organizations/{listLocalOrganizations.js → readModel/listLocalOrganizations.js} +8 -8
- package/workflows/organizations/readModel/listLocalOrganizations.js.map +1 -0
- package/workflows/organizations/{localReadModelDetails.d.ts → readModel/localReadModelDetails.d.ts} +3 -3
- package/workflows/organizations/{localReadModelDetails.js → readModel/localReadModelDetails.js} +6 -6
- package/workflows/organizations/readModel/localReadModelDetails.js.map +1 -0
- package/workflows/organizations/{organizationPresentationAccessState.js → readModel/organizationPresentationAccessState.js} +1 -1
- package/workflows/organizations/readModel/organizationPresentationAccessState.js.map +1 -0
- package/workflows/organizations/{organizationPresentationFailures.js → readModel/organizationPresentationFailures.js} +1 -1
- package/workflows/organizations/{readModelProjection.d.ts → readModel/readModelProjection.d.ts} +5 -5
- package/workflows/organizations/{readModelProjection.js → readModel/readModelProjection.js} +6 -6
- package/workflows/organizations/readModel/readModelProjection.js.map +1 -0
- package/workflows/organizations/{authoredPrincipalPolicyWarmer.js → rematerialization/authoredPrincipalPolicyWarmer.js} +2 -2
- package/workflows/organizations/rematerialization/authoredPrincipalPolicyWarmer.js.map +1 -0
- package/workflows/organizations/{precedingPrincipalRematerialization.js → rematerialization/precedingPrincipalRematerialization.js} +1 -1
- package/workflows/organizations/rematerialization/precedingPrincipalRematerialization.js.map +1 -0
- package/workflows/organizations/{principalContainerRematerialization.js → rematerialization/principalContainerRematerialization.js} +13 -13
- package/workflows/organizations/rematerialization/principalContainerRematerialization.js.map +1 -0
- package/workflows/organizations/{principalContainerRematerializationPlanning.js → rematerialization/principalContainerRematerializationPlanning.js} +2 -2
- package/workflows/organizations/rematerialization/principalContainerRematerializationPlanning.js.map +1 -0
- package/workflows/organizations/{principalContainerRematerializationTargets.js → rematerialization/principalContainerRematerializationTargets.js} +3 -3
- package/workflows/organizations/rematerialization/principalContainerRematerializationTargets.js.map +1 -0
- package/workflows/principals/{acknowledgedPrincipalCurrents.d.ts → acknowledgements/acknowledgedPrincipalCurrents.d.ts} +6 -6
- package/workflows/principals/{acknowledgedPrincipalCurrents.js → acknowledgements/acknowledgedPrincipalCurrents.js} +7 -7
- package/workflows/principals/acknowledgements/acknowledgedPrincipalCurrents.js.map +1 -0
- package/workflows/principals/{acknowledgedPrincipalPredecessor.d.ts → acknowledgements/acknowledgedPrincipalPredecessor.d.ts} +10 -10
- package/workflows/principals/{acknowledgedPrincipalPredecessor.js → acknowledgements/acknowledgedPrincipalPredecessor.js} +9 -9
- package/workflows/principals/acknowledgements/acknowledgedPrincipalPredecessor.js.map +1 -0
- package/workflows/principals/{initialPrincipalCurrentPublication.js → acknowledgements/initialPrincipalCurrentPublication.js} +7 -7
- package/workflows/principals/acknowledgements/initialPrincipalCurrentPublication.js.map +1 -0
- package/workflows/principals/{principalAcknowledgementChecks.d.ts → acknowledgements/principalAcknowledgementChecks.d.ts} +3 -3
- package/workflows/principals/{principalCurrentPublicationSeal.js → acknowledgements/principalCurrentPublicationSeal.js} +3 -3
- package/workflows/principals/acknowledgements/principalCurrentPublicationSeal.js.map +1 -0
- package/workflows/principals/{reconcileAcknowledgedPrincipalCurrent.js → acknowledgements/reconcileAcknowledgedPrincipalCurrent.js} +6 -6
- package/workflows/principals/acknowledgements/reconcileAcknowledgedPrincipalCurrent.js.map +1 -0
- package/workflows/principals/{loadRecoveredPrincipalHistoryPage.d.ts → historyRecovery/loadRecoveredPrincipalHistoryPage.d.ts} +1 -1
- package/workflows/principals/{loadRecoveredPrincipalHistoryPage.js → historyRecovery/loadRecoveredPrincipalHistoryPage.js} +7 -7
- package/workflows/principals/historyRecovery/loadRecoveredPrincipalHistoryPage.js.map +1 -0
- package/workflows/principals/{principalHistoryRecoveryAuthority.js → historyRecovery/principalHistoryRecoveryAuthority.js} +2 -2
- package/workflows/principals/historyRecovery/principalHistoryRecoveryAuthority.js.map +1 -0
- package/workflows/principals/{principalHistoryRecoveryPrefix.js → historyRecovery/principalHistoryRecoveryPrefix.js} +5 -5
- package/workflows/principals/historyRecovery/principalHistoryRecoveryPrefix.js.map +1 -0
- package/workflows/principals/{principalHistoryRecoveryReferences.js → historyRecovery/principalHistoryRecoveryReferences.js} +4 -4
- package/workflows/principals/historyRecovery/principalHistoryRecoveryReferences.js.map +1 -0
- package/workflows/principals/{principalHistoryRecoveryStage.js → historyRecovery/principalHistoryRecoveryStage.js} +4 -4
- package/workflows/principals/historyRecovery/principalHistoryRecoveryStage.js.map +1 -0
- package/workflows/principals/{principalHistoryRecoveryTypes.d.ts → historyRecovery/principalHistoryRecoveryTypes.d.ts} +5 -5
- package/workflows/principals/{principalHistoryRecoveryTypes.js → historyRecovery/principalHistoryRecoveryTypes.js} +1 -1
- package/workflows/principals/historyRecovery/principalHistoryRecoveryTypes.js.map +1 -0
- package/workflows/principals/{principalHistoryRecoveryVerification.js → historyRecovery/principalHistoryRecoveryVerification.js} +1 -1
- package/workflows/principals/{recoverCurrentOrganizationPolicy.js → historyRecovery/recoverCurrentOrganizationPolicy.js} +4 -4
- package/workflows/principals/historyRecovery/recoverCurrentOrganizationPolicy.js.map +1 -0
- package/workflows/principals/{recoverPrincipalHistoryPage.js → historyRecovery/recoverPrincipalHistoryPage.js} +2 -2
- package/workflows/principals/{recoverPrincipalPolicyHistory.js → historyRecovery/recoverPrincipalPolicyHistory.js} +8 -8
- package/workflows/principals/historyRecovery/recoverPrincipalPolicyHistory.js.map +1 -0
- package/workflows/principals/{recoverScopedPrincipalPolicyHistory.d.ts → historyRecovery/recoverScopedPrincipalPolicyHistory.d.ts} +3 -3
- package/workflows/principals/{recoverScopedPrincipalPolicyHistory.js → historyRecovery/recoverScopedPrincipalPolicyHistory.js} +7 -7
- package/workflows/principals/historyRecovery/recoverScopedPrincipalPolicyHistory.js.map +1 -0
- package/workflows/principals/index.d.ts +6 -6
- package/workflows/principals/index.js +6 -6
- package/workflows/principals/index.js.map +1 -1
- package/workflows/principals/{policyCache.d.ts → policyCache/index.d.ts} +5 -5
- package/workflows/principals/{policyCache.js → policyCache/index.js} +10 -10
- package/workflows/principals/policyCache/index.js.map +1 -0
- package/workflows/principals/{principalPolicyCacheAdvance.js → policyCache/principalPolicyCacheAdvance.js} +2 -2
- package/workflows/principals/policyCache/principalPolicyCacheAdvance.js.map +1 -0
- package/workflows/principals/{principalPolicyCacheValidation.js → policyCache/principalPolicyCacheValidation.js} +3 -3
- package/workflows/principals/policyCache/principalPolicyCacheValidation.js.map +1 -0
- package/workflows/principals/{principalPolicyOrganizationScope.js → policyCache/principalPolicyOrganizationScope.js} +7 -7
- package/workflows/principals/policyCache/principalPolicyOrganizationScope.js.map +1 -0
- package/workflows/principals/{publicPrincipalHistoryAuthority.js → publicHistory/publicPrincipalHistoryAuthority.js} +3 -3
- package/workflows/principals/publicHistory/publicPrincipalHistoryAuthority.js.map +1 -0
- package/workflows/principals/{publicPrincipalHistoryPage.js → publicHistory/publicPrincipalHistoryPage.js} +6 -6
- package/workflows/principals/publicHistory/publicPrincipalHistoryPage.js.map +1 -0
- package/workflows/principals/{publicPrincipalHistoryProgress.js → publicHistory/publicPrincipalHistoryProgress.js} +8 -8
- package/workflows/principals/publicHistory/publicPrincipalHistoryProgress.js.map +1 -0
- package/workflows/principals/{publicPrincipalHistoryTypes.d.ts → publicHistory/publicPrincipalHistoryTypes.d.ts} +7 -7
- package/workflows/principals/publicHistory/publicPrincipalHistoryTypes.js.map +1 -0
- package/workflows/principals/{publicProjectionDirectory.js → publicHistory/publicProjectionDirectory.js} +2 -2
- package/workflows/principals/publicHistory/publicProjectionDirectory.js.map +1 -0
- package/workflows/principals/{publicProjectionPrincipal.js → publicHistory/publicProjectionPrincipal.js} +4 -4
- package/workflows/principals/publicHistory/publicProjectionPrincipal.js.map +1 -0
- package/workflows/principals/{recoverProjectionPolicyHistory.d.ts → publicHistory/recoverProjectionPolicyHistory.d.ts} +2 -2
- package/workflows/principals/{recoverProjectionPolicyHistory.js → publicHistory/recoverProjectionPolicyHistory.js} +3 -3
- package/workflows/principals/publicHistory/recoverProjectionPolicyHistory.js.map +1 -0
- package/workflows/principals/{recoverPublicPrincipalHistory.js → publicHistory/recoverPublicPrincipalHistory.js} +7 -7
- package/workflows/principals/publicHistory/recoverPublicPrincipalHistory.js.map +1 -0
- package/workflows/principals/{selectPublicPrincipalHistory.js → publicHistory/selectPublicPrincipalHistory.js} +5 -5
- package/workflows/principals/publicHistory/selectPublicPrincipalHistory.js.map +1 -0
- package/workflows/principals/{principalCurrentRecoveryBatch.js → recoveryOperation/principalCurrentRecoveryBatch.js} +2 -2
- package/workflows/principals/recoveryOperation/principalCurrentRecoveryBatch.js.map +1 -0
- package/workflows/principals/{principalRecoveryDirectory.d.ts → recoveryOperation/principalRecoveryDirectory.d.ts} +3 -3
- package/workflows/principals/{principalRecoveryDirectory.js → recoveryOperation/principalRecoveryDirectory.js} +9 -9
- package/workflows/principals/recoveryOperation/principalRecoveryDirectory.js.map +1 -0
- package/workflows/principals/recoveryOperation/principalRecoveryDiscoveryPage.js.map +1 -0
- package/workflows/principals/{principalRecoveryLocalPreference.js → recoveryOperation/principalRecoveryLocalPreference.js} +4 -4
- package/workflows/principals/recoveryOperation/principalRecoveryLocalPreference.js.map +1 -0
- package/workflows/principals/{principalRecoveryMemo.d.ts → recoveryOperation/principalRecoveryMemo.d.ts} +2 -2
- package/workflows/principals/{principalRecoveryMemo.js → recoveryOperation/principalRecoveryMemo.js} +4 -4
- package/workflows/principals/recoveryOperation/principalRecoveryMemo.js.map +1 -0
- package/workflows/principals/{principalRecoveryMemoValidity.js → recoveryOperation/principalRecoveryMemoValidity.js} +2 -2
- package/workflows/principals/recoveryOperation/principalRecoveryMemoValidity.js.map +1 -0
- package/workflows/principals/{principalRecoveryOutage.js → recoveryOperation/principalRecoveryOutage.js} +5 -5
- package/workflows/principals/recoveryOperation/principalRecoveryOutage.js.map +1 -0
- package/workflows/principals/runtimePolicyRecovery.js +3 -3
- package/workflows/principals/runtimePolicyRecovery.js.map +1 -1
- package/workflows/principals/runtimeProjectionPolicyRecovery.js +3 -3
- package/workflows/principals/runtimeProjectionPolicyRecovery.js.map +1 -1
- package/workflows/registration/organizationProvisioningArtifacts.d.ts +1 -1
- package/workflows/registration/provisionedPrincipalHistory.js +1 -1
- package/workflows/registration/provisionedPrincipalHistory.js.map +1 -1
- package/workflows/registration/provisionedProfileDocument.js +1 -1
- package/workflows/registration/provisionedProfileDocument.js.map +1 -1
- package/workflows/registration/provisioningBootstrapBuilders.js +2 -2
- package/workflows/registration/provisioningBootstrapBuilders.js.map +1 -1
- package/workflows/registration/registerIdentity.js +2 -2
- package/workflows/registration/registerIdentity.js.map +1 -1
- package/workflows/sync/remoteReset.js +1 -1
- package/workflows/sync/remoteReset.js.map +1 -1
- package/workflows/blobs/attachmentBindingVerification.js.map +0 -1
- package/workflows/blobs/attachmentDecryptor.js.map +0 -1
- package/workflows/blobs/attachmentKeyAuthenticator.js.map +0 -1
- package/workflows/blobs/automaticMultipartUpload.js.map +0 -1
- package/workflows/blobs/blobChunkDecryption.js.map +0 -1
- package/workflows/blobs/decrypt.js.map +0 -1
- package/workflows/blobs/hydrate.js.map +0 -1
- package/workflows/blobs/hydrationResults.js.map +0 -1
- package/workflows/blobs/multipartFirstParts.js.map +0 -1
- package/workflows/blobs/multipartStageFailures.js.map +0 -1
- package/workflows/blobs/multipartStageResolution.js.map +0 -1
- package/workflows/blobs/multipartUpload.js.map +0 -1
- package/workflows/blobs/retainedAttachmentVerification.js.map +0 -1
- package/workflows/blobs/upload.js.map +0 -1
- package/workflows/blobs/verifiedWrapScope.js.map +0 -1
- package/workflows/blobs/writerProjection.js.map +0 -1
- package/workflows/documents/attachmentPersistence.js.map +0 -1
- package/workflows/documents/blobMutationLock.js.map +0 -1
- package/workflows/documents/create.js.map +0 -1
- package/workflows/documents/createAdoption.js.map +0 -1
- package/workflows/documents/createProjectionFetch.js.map +0 -1
- package/workflows/documents/createResponse.js.map +0 -1
- package/workflows/documents/documentCreationPersistence.js.map +0 -1
- package/workflows/documents/initialSync.js.map +0 -1
- package/workflows/documents/linkSet.js.map +0 -1
- package/workflows/documents/linkSetAuthority.js.map +0 -1
- package/workflows/documents/linkSetBlobRewraps.js.map +0 -1
- package/workflows/documents/linkSetProjectionSeed.js.map +0 -1
- package/workflows/documents/linkSetRemote.js.map +0 -1
- package/workflows/documents/orphanBlobReclaimState.js.map +0 -1
- package/workflows/documents/orphanBlobReclaims.js.map +0 -1
- package/workflows/documents/persistedDocumentRemoval.js.map +0 -1
- package/workflows/documents/purge.js.map +0 -1
- package/workflows/documents/readOnlyProjectionFailure.js.map +0 -1
- package/workflows/documents/readOnlySync.js.map +0 -1
- package/workflows/documents/reportDocumentSyncQuarantine.js.map +0 -1
- package/workflows/documents/subtreePurgeScope.js.map +0 -1
- package/workflows/documents/sync.js.map +0 -1
- package/workflows/documents/syncAbandon.js.map +0 -1
- package/workflows/documents/syncAttemptPlanning.js.map +0 -1
- package/workflows/documents/syncAttemptState.js.map +0 -1
- package/workflows/documents/syncAutomaticContainerRekeys.js.map +0 -1
- package/workflows/documents/syncContainerRekeyPreparation.js.map +0 -1
- package/workflows/documents/syncContainerRekeyProjection.js.map +0 -1
- package/workflows/documents/syncContainerRekeys.js.map +0 -1
- package/workflows/documents/syncContentKeys.js.map +0 -1
- package/workflows/documents/syncFailureClassification.js.map +0 -1
- package/workflows/documents/syncFailures.js.map +0 -1
- package/workflows/documents/syncLane.js.map +0 -1
- package/workflows/documents/syncPlanIdentity.js.map +0 -1
- package/workflows/documents/syncPlanMaterial.js.map +0 -1
- package/workflows/documents/syncPlanProjection.js.map +0 -1
- package/workflows/documents/syncPlanRequestBounds.js.map +0 -1
- package/workflows/documents/syncPolicyRepair.js.map +0 -1
- package/workflows/documents/syncRecoveryRekey.js.map +0 -1
- package/workflows/documents/syncRepairAbandon.js.map +0 -1
- package/workflows/documents/syncRepairAccess.js.map +0 -1
- package/workflows/documents/syncResponseResult.js.map +0 -1
- package/workflows/documents/syncSubmittedResult.js.map +0 -1
- package/workflows/organizations/acknowledgedDirectoryBindings.js.map +0 -1
- package/workflows/organizations/authoredPrincipalPolicyWarmer.js.map +0 -1
- package/workflows/organizations/commitCurrentGroupPolicyMutation.js.map +0 -1
- package/workflows/organizations/createCurrentOrganizationGroup.js.map +0 -1
- package/workflows/organizations/createOrganization.js.map +0 -1
- package/workflows/organizations/currentGroupMetadataAuthority.js.map +0 -1
- package/workflows/organizations/currentGroupMutationReferences.js.map +0 -1
- package/workflows/organizations/currentGroupPolicyMutationContext.js.map +0 -1
- package/workflows/organizations/currentOrganizationGroupNames.js.map +0 -1
- package/workflows/organizations/currentOrganizationMutationAuthority.js.map +0 -1
- package/workflows/organizations/currentOrganizationMutationRetention.js.map +0 -1
- package/workflows/organizations/currentPolicyMutationAcknowledgement.js.map +0 -1
- package/workflows/organizations/currentPrincipalMutationLease.js.map +0 -1
- package/workflows/organizations/dataUsageReadModel.js.map +0 -1
- package/workflows/organizations/deleteCurrentOrganizationGroup.js.map +0 -1
- package/workflows/organizations/deleteOrganizationGroup.js.map +0 -1
- package/workflows/organizations/groupCreation.js.map +0 -1
- package/workflows/organizations/groupMembershipName.js.map +0 -1
- package/workflows/organizations/groupMetadataAccess.js.map +0 -1
- package/workflows/organizations/groupMetadataBinding.js.map +0 -1
- package/workflows/organizations/groupMetadataContainerAuthority.js.map +0 -1
- package/workflows/organizations/groupMetadataRootBinding.js.map +0 -1
- package/workflows/organizations/groupMetadataRuntime.js.map +0 -1
- package/workflows/organizations/groupNameUniqueness.js.map +0 -1
- package/workflows/organizations/groupPolicyHistoryPage.js.map +0 -1
- package/workflows/organizations/groupPolicyMutationAcknowledgement.js.map +0 -1
- package/workflows/organizations/groupPolicyMutationContext.js.map +0 -1
- package/workflows/organizations/groupPolicyMutationEvidence.js.map +0 -1
- package/workflows/organizations/groupPolicyRequests.js.map +0 -1
- package/workflows/organizations/groupPolicyVerification.js.map +0 -1
- package/workflows/organizations/listLocalOrganizations.js.map +0 -1
- package/workflows/organizations/loadPolicyHistoryDetails.js.map +0 -1
- package/workflows/organizations/localReadModelDetails.js.map +0 -1
- package/workflows/organizations/organizationGroupDirectory.js.map +0 -1
- package/workflows/organizations/organizationGroupNamePolicies.js.map +0 -1
- package/workflows/organizations/organizationGroupNames.js.map +0 -1
- package/workflows/organizations/organizationPolicyHistoryDetails.js.map +0 -1
- package/workflows/organizations/organizationPolicyHistoryVerification.js.map +0 -1
- package/workflows/organizations/organizationPresentationAccessState.js.map +0 -1
- package/workflows/organizations/organizationProvisioningAttempt.js.map +0 -1
- package/workflows/organizations/organizationReplacementVerification.js.map +0 -1
- package/workflows/organizations/policyHistoryAccessDenial.js.map +0 -1
- package/workflows/organizations/policyHistoryCache.js.map +0 -1
- package/workflows/organizations/precedingPrincipalRematerialization.js.map +0 -1
- package/workflows/organizations/principalContainerRematerialization.js.map +0 -1
- package/workflows/organizations/principalContainerRematerializationPlanning.js.map +0 -1
- package/workflows/organizations/principalContainerRematerializationTargets.js.map +0 -1
- package/workflows/organizations/principalMutationJournalManagement.js.map +0 -1
- package/workflows/organizations/principalMutationJournalSession.js.map +0 -1
- package/workflows/organizations/principalMutationReceipt.js.map +0 -1
- package/workflows/organizations/principalOperationReceipt.js.map +0 -1
- package/workflows/organizations/principalPolicy.js.map +0 -1
- package/workflows/organizations/principalPolicyApi.js.map +0 -1
- package/workflows/organizations/principalPolicyReceiptArtifacts.js.map +0 -1
- package/workflows/organizations/principalPolicyRecipients.js.map +0 -1
- package/workflows/organizations/readModel.js.map +0 -1
- package/workflows/organizations/readModelProjection.js.map +0 -1
- package/workflows/organizations/retainAcknowledgedPrincipalCurrents.d.ts +0 -6
- package/workflows/organizations/retainAcknowledgedPrincipalCurrents.js.map +0 -1
- package/workflows/organizations/runtimeCurrentGroupMutation.js.map +0 -1
- package/workflows/organizations/runtimeCurrentOrganizationMutation.js.map +0 -1
- package/workflows/organizations/runtimeGroupMetadataAuthority.js.map +0 -1
- package/workflows/organizations/submitGroupPolicyCommit.js.map +0 -1
- package/workflows/principals/acknowledgedPrincipalCurrents.js.map +0 -1
- package/workflows/principals/acknowledgedPrincipalPredecessor.js.map +0 -1
- package/workflows/principals/initialPrincipalCurrentPublication.js.map +0 -1
- package/workflows/principals/loadRecoveredPrincipalHistoryPage.js.map +0 -1
- package/workflows/principals/policyCache.js.map +0 -1
- package/workflows/principals/principalCurrentPublicationSeal.js.map +0 -1
- package/workflows/principals/principalCurrentRecoveryBatch.js.map +0 -1
- package/workflows/principals/principalHistoryRecoveryAuthority.js.map +0 -1
- package/workflows/principals/principalHistoryRecoveryPrefix.js.map +0 -1
- package/workflows/principals/principalHistoryRecoveryReferences.js.map +0 -1
- package/workflows/principals/principalHistoryRecoveryStage.js.map +0 -1
- package/workflows/principals/principalHistoryRecoveryTypes.js.map +0 -1
- package/workflows/principals/principalPolicyCacheAdvance.js.map +0 -1
- package/workflows/principals/principalPolicyCacheValidation.js.map +0 -1
- package/workflows/principals/principalPolicyOrganizationScope.js.map +0 -1
- package/workflows/principals/principalRecoveryDirectory.js.map +0 -1
- package/workflows/principals/principalRecoveryDiscoveryPage.js.map +0 -1
- package/workflows/principals/principalRecoveryLocalPreference.js.map +0 -1
- package/workflows/principals/principalRecoveryMemo.js.map +0 -1
- package/workflows/principals/principalRecoveryMemoValidity.js.map +0 -1
- package/workflows/principals/principalRecoveryOutage.js.map +0 -1
- package/workflows/principals/publicPrincipalHistoryAuthority.js.map +0 -1
- package/workflows/principals/publicPrincipalHistoryPage.js.map +0 -1
- package/workflows/principals/publicPrincipalHistoryProgress.js.map +0 -1
- package/workflows/principals/publicPrincipalHistoryTypes.js.map +0 -1
- package/workflows/principals/publicProjectionDirectory.js.map +0 -1
- package/workflows/principals/publicProjectionPrincipal.js.map +0 -1
- package/workflows/principals/reconcileAcknowledgedPrincipalCurrent.js.map +0 -1
- package/workflows/principals/recoverCurrentOrganizationPolicy.js.map +0 -1
- package/workflows/principals/recoverPrincipalPolicyHistory.js.map +0 -1
- package/workflows/principals/recoverProjectionPolicyHistory.js.map +0 -1
- package/workflows/principals/recoverPublicPrincipalHistory.js.map +0 -1
- package/workflows/principals/recoverScopedPrincipalPolicyHistory.js.map +0 -1
- package/workflows/principals/selectPublicPrincipalHistory.js.map +0 -1
- /package/workflows/blobs/{readAttachmentTransfer.js → hydration/readAttachmentTransfer.js} +0 -0
- /package/workflows/blobs/{readAttachmentTransfer.js.map → hydration/readAttachmentTransfer.js.map} +0 -0
- /package/workflows/blobs/{multipartStageResolution.js → upload/multipartStageResolution.js} +0 -0
- /package/workflows/documents/{attachmentPersistence.js → attachments/attachmentPersistence.js} +0 -0
- /package/workflows/documents/{orphanBlobReclaimState.js → attachments/orphanBlobReclaimState.js} +0 -0
- /package/workflows/documents/{createProjection.js → create/createProjection.js} +0 -0
- /package/workflows/documents/{createProjection.js.map → create/createProjection.js.map} +0 -0
- /package/workflows/documents/{createProjectionFetch.js → create/createProjectionFetch.js} +0 -0
- /package/workflows/documents/{reportDocumentSyncQuarantine.js → sync/reportDocumentSyncQuarantine.js} +0 -0
- /package/workflows/documents/{syncAttemptState.js → sync/syncAttemptState.js} +0 -0
- /package/workflows/documents/{syncTrace.d.ts → sync/syncTrace.d.ts} +0 -0
- /package/workflows/documents/{syncTrace.js.map → sync/syncTrace.js.map} +0 -0
- /package/workflows/documents/{syncFailureClearance.d.ts → syncFailures/syncFailureClearance.d.ts} +0 -0
- /package/workflows/documents/{syncFailureClearance.js → syncFailures/syncFailureClearance.js} +0 -0
- /package/workflows/documents/{syncFailureClearance.js.map → syncFailures/syncFailureClearance.js.map} +0 -0
- /package/workflows/documents/{syncRepairAbandon.js → syncFailures/syncRepairAbandon.js} +0 -0
- /package/workflows/documents/{syncPlanProjection.js → syncPlan/syncPlanProjection.js} +0 -0
- /package/workflows/documents/{syncRekeyCommit.js.map → syncRekeys/syncRekeyCommit.js.map} +0 -0
- /package/workflows/organizations/{groupMetadataErrors.js.map → groupMetadata/groupMetadataErrors.js.map} +0 -0
- /package/workflows/organizations/{groupMutationAuthorization.js → groupPolicy/groupMutationAuthorization.js} +0 -0
- /package/workflows/organizations/{groupMutationAuthorization.js.map → groupPolicy/groupMutationAuthorization.js.map} +0 -0
- /package/workflows/organizations/{groupPolicyMutationHead.js.map → groupPolicy/groupPolicyMutationHead.js.map} +0 -0
- /package/workflows/organizations/{groupPolicyHistoryPage.js → policyHistory/groupPolicyHistoryPage.js} +0 -0
- /package/workflows/organizations/{policyHistoryReadModel.js → policyHistory/policyHistoryReadModel.js} +0 -0
- /package/workflows/organizations/{policyHistoryReadModel.js.map → policyHistory/policyHistoryReadModel.js.map} +0 -0
- /package/workflows/organizations/{policyHistoryTypes.js → policyHistory/policyHistoryTypes.js} +0 -0
- /package/workflows/organizations/{policyHistoryTypes.js.map → policyHistory/policyHistoryTypes.js.map} +0 -0
- /package/workflows/organizations/{principalPolicyApi.js → principalPolicy/principalPolicyApi.js} +0 -0
- /package/workflows/organizations/{principalPolicyRequest.js.map → principalPolicy/principalPolicyRequest.js.map} +0 -0
- /package/workflows/organizations/{organizationPresentationFailures.js.map → readModel/organizationPresentationFailures.js.map} +0 -0
- /package/workflows/principals/{principalAcknowledgementChecks.js → acknowledgements/principalAcknowledgementChecks.js} +0 -0
- /package/workflows/principals/{principalAcknowledgementChecks.js.map → acknowledgements/principalAcknowledgementChecks.js.map} +0 -0
- /package/workflows/principals/{principalHistoryRecoveryVerification.js.map → historyRecovery/principalHistoryRecoveryVerification.js.map} +0 -0
- /package/workflows/principals/{recoverPrincipalHistoryPage.js.map → historyRecovery/recoverPrincipalHistoryPage.js.map} +0 -0
- /package/workflows/principals/{recoverPrincipalPolicyHistory.d.ts → historyRecovery/recoverPrincipalPolicyHistory.d.ts} +0 -0
- /package/workflows/principals/{principalPolicyCacheScope.js → policyCache/principalPolicyCacheScope.js} +0 -0
- /package/workflows/principals/{principalPolicyCacheScope.js.map → policyCache/principalPolicyCacheScope.js.map} +0 -0
- /package/workflows/principals/{publicPrincipalHistoryTypes.js → publicHistory/publicPrincipalHistoryTypes.js} +0 -0
- /package/workflows/principals/{principalRecoveryDiscoveryPage.js → recoveryOperation/principalRecoveryDiscoveryPage.js} +0 -0
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"multipartFirstParts.js","sourceRoot":"","sources":["multipartFirstParts.ts"],"names":[],"mappings":"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","sourcesContent":["import { describeMultipartBlobPart } from \"@tearleads/api-client\";\nimport { bytesToHex } from \"@tearleads/crypto\";\nimport type { InitiateMultipartBlobStageResponse } from \"@tearleads/validators/response\";\nimport {\n MAX_INITIATE_PART_UPLOADS,\n type MultipartBlobPartDescriptor,\n type MultipartBlobPartUploadSource,\n} from \"@tearleads/validators/util\";\nimport type { BlobBytes } from \"../../data/blobs/blobContracts\";\nimport {\n acquireBlobTransferPermit,\n type BlobTransferPermit,\n tryAcquireBlobTransferPermit,\n} from \"../../data/blobs/transferPool\";\nimport type { BlobEncryptionPlan } from \"../../data/documents/blob/shared/crypto\";\n\nexport interface PreparedMultipartPart {\n readonly bytes: BlobBytes;\n readonly sha256: string;\n}\n\n/**\n * A first part's bytes and the transfer-pool permit that pays for them: the\n * bytes exist before their upload can start, so they hold a slot of the\n * client's byte-I/O bound until the upload that sends them releases it.\n */\nexport interface PreparedFirstPart extends PreparedMultipartPart {\n readonly permit: BlobTransferPermit;\n}\n\n/**\n * The parts a new stage's upload starts with, encrypted once up front: their\n * descriptors ride on the stage initiation, and their bytes are handed to the\n * upload workers instead of being encrypted a second time.\n */\nexport interface MultipartFirstParts {\n readonly descriptors: readonly MultipartBlobPartDescriptor[];\n readonly prepared: Map<number, PreparedFirstPart>;\n}\n\n/** Return the pool slots of first parts no upload consumed. */\nexport function releasePreparedParts(\n prepared: Map<number, PreparedFirstPart>,\n): void {\n for (const part of prepared.values()) {\n part.permit.release();\n }\n prepared.clear();\n}\n\n/**\n * One permit is awaited; more are taken only if free right now. Two uploads\n * each waiting for a second slot while holding a first could otherwise\n * deadlock the pool, since a held slot frees only when its part uploads.\n */\nasync function acquireFirstPartPermits(\n client: object,\n limit: number,\n): Promise<BlobTransferPermit[]> {\n const permits = [await acquireBlobTransferPermit(client)];\n while (permits.length < limit) {\n const permit = tryAcquireBlobTransferPermit(client);\n if (!permit) break;\n permits.push(permit);\n }\n return permits;\n}\n\n/**\n * Where each part's bytes go. Sources the stage initiation issued are used\n * once; a store that cannot sign (`api`) needs no per-part authorization at\n * all, and a part with no source authorizes just before it is sent.\n */\nexport interface MultipartPartSources {\n readonly apiTransport: boolean;\n readonly issued: Map<number, MultipartBlobPartUploadSource>;\n}\n\nexport async function sha256BytesHex(bytes: BlobBytes): Promise<string> {\n return bytesToHex(\n new Uint8Array(await crypto.subtle.digest(\"SHA-256\", bytes)),\n );\n}\n\nexport async function prepareFirstMultipartParts(\n client: object,\n encryption: BlobEncryptionPlan,\n concurrency: number,\n): Promise<MultipartFirstParts> {\n const permits = await acquireFirstPartPermits(\n client,\n Math.min(encryption.partCount, concurrency, MAX_INITIATE_PART_UPLOADS),\n );\n const descriptors: MultipartBlobPartDescriptor[] = [];\n const prepared = new Map<number, PreparedFirstPart>();\n try {\n for (const [partIndex, permit] of permits.entries()) {\n const bytes = await encryption.encryptPart(partIndex);\n if (bytes.byteLength !== encryption.getPartByteLength(partIndex)) {\n throw new Error(\n `Encrypted blob part ${partIndex + 1} byte length mismatch: expected ${encryption.getPartByteLength(partIndex).toLocaleString()}, received ${bytes.byteLength.toLocaleString()}.`,\n );\n }\n const sha256 = await sha256BytesHex(bytes);\n prepared.set(partIndex, { bytes, permit, sha256 });\n descriptors.push(describeMultipartBlobPart(partIndex + 1, bytes));\n }\n } catch (error) {\n for (const permit of permits) permit.release();\n throw error;\n }\n return { descriptors, prepared };\n}\n\n/**\n * The initiation must return exactly one source per described part, for that\n * part's number, length, and checksum, and every source of one stage must use\n * the same transport.\n */\nexport function readIssuedPartSources(\n descriptors: readonly MultipartBlobPartDescriptor[],\n stage: Pick<InitiateMultipartBlobStageResponse, \"partUploads\">,\n): MultipartPartSources {\n const issued = new Map<number, MultipartBlobPartUploadSource>();\n const kinds = new Set(stage.partUploads.map((upload) => upload.source.kind));\n const matches =\n stage.partUploads.length === descriptors.length &&\n kinds.size === 1 &&\n descriptors.every((descriptor, index) => {\n const upload = stage.partUploads[index];\n return (\n upload?.partNumber === descriptor.partNumber &&\n upload.byteLength === descriptor.byteLength &&\n upload.contentMd5 === descriptor.contentMd5\n );\n });\n if (!matches) {\n throw new Error(\n \"Multipart blob stage initiation part uploads do not match its request.\",\n );\n }\n for (const upload of stage.partUploads) {\n issued.set(upload.partNumber, upload.source);\n }\n return { apiTransport: kinds.has(\"api\"), issued };\n}\n\n/** Use each issued source once; retries and later parts authorize anew. */\nexport function takePartSource(\n sources: MultipartPartSources,\n partNumber: number,\n): MultipartBlobPartUploadSource | undefined {\n const issued = sources.issued.get(partNumber);\n sources.issued.delete(partNumber);\n return issued ?? (sources.apiTransport ? { kind: \"api\" } : undefined);\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"multipartStageFailures.js","sourceRoot":"","sources":["multipartStageFailures.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gCAAgC,EAAE,MAAM,gCAAgC,CAAC;AAUlF,MAAM,UAAU,kBAAkB,CAAC,OAAe;IAChD,OAAO,2BAA2B,kBAAkB,CAAC,OAAO,CAAC,EAAE,CAAC;AAClE,CAAC;AAED,MAAM,UAAU,0BAA0B,CAAC,KAI1C;IACC,MAAM,OAAO,GAAG,KAAK,CAAC,SAAS,CAAC,iBAAiB,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAC5E,OAAO,OAAO;QACZ,CAAC,CAAC,GAAG,KAAK,CAAC,QAAQ,0BAA0B,OAAO,EAAE;QACtD,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC;AACrB,CAAC;AAED,SAAS,+BAA+B,CACtC,OAAmC;IAEnC,OAAO,CACL,OAAO,EAAE,IAAI,KAAK,MAAM;QACxB,CAAC,CAAC,OAAO,CAAC,MAAM,KAAK,GAAG;YACtB,OAAO,CAAC,IAAI,KAAK,gCAAgC,CAAC,QAAQ,CAAC;YAC3D,CAAC,OAAO,CAAC,MAAM,KAAK,GAAG;gBACrB,OAAO,CAAC,IAAI,KAAK,gCAAgC,CAAC,OAAO,CAAC,CAAC,CAChE,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,+BAA+B,CAAC,KAMrD;IACC,MAAM,OAAO,GAAG;QACd,MAAM,EAAE,KAAc;QACtB,IAAI,EAAE,kBAAkB,CAAC,KAAK,CAAC,OAAO,CAAC;KACxC,CAAC;IACF,MAAM,OAAO,GAAG,KAAK,CAAC,SAAS,CAAC,iBAAiB,EAAE,CAAC,OAAO,CAAC,CAAC;IAC7D,IAAI,CAAC,+BAA+B,CAAC,OAAO,CAAC,EAAE,CAAC;QAC9C,MAAM,IAAI,KAAK,CACb,0BAA0B,CAAC;YACzB,SAAS,EAAE,KAAK,CAAC,SAAS;YAC1B,QAAQ,EAAE,uDAAuD,KAAK,CAAC,OAAO,GAAG;YACjF,OAAO;SACR,CAAC,CACH,CAAC;IACJ,CAAC;IACD,IAAI,KAAK,CAAC,kBAAkB,EAAE,CAAC;QAC7B,MAAM,KAAK,CAAC,kBAAkB,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAC9C,MAAM,IAAI,KAAK,CACb,sEAAsE,CACvE,CAAC;IACJ,CAAC;AACH,CAAC","sourcesContent":["import { MULTIPART_BLOB_STAGE_ERROR_CODES } from \"@tearleads/validators/response\";\nimport type { BlobAttachmentApi } from \"../../data/documents/blob/shared/types\";\n\ntype RequestFailureInput = Parameters<\n NonNullable<BlobAttachmentApi[\"getRequestFailure\"]>\n>[0];\ntype RequestFailure = ReturnType<\n NonNullable<BlobAttachmentApi[\"getRequestFailure\"]>\n>;\n\nexport function multipartStagePath(stageId: string): string {\n return `/blobs/stages/multipart/${encodeURIComponent(stageId)}`;\n}\n\nexport function multipartApiFailureMessage(input: {\n readonly apiClient: BlobAttachmentApi;\n readonly fallback: string;\n readonly request: RequestFailureInput;\n}): string {\n const failure = input.apiClient.getRequestFailure?.(input.request)?.message;\n return failure\n ? `${input.fallback} Last request failure: ${failure}`\n : input.fallback;\n}\n\nfunction provesMultipartStageReplacement(\n failure: RequestFailure | undefined,\n): boolean {\n return (\n failure?.kind === \"http\" &&\n ((failure.status === 404 &&\n failure.code === MULTIPART_BLOB_STAGE_ERROR_CODES.notFound) ||\n (failure.status === 409 &&\n failure.code === MULTIPART_BLOB_STAGE_ERROR_CODES.expired))\n );\n}\n\nexport async function assertMultipartStageReplaceable(input: {\n readonly apiClient: BlobAttachmentApi;\n readonly onStageUnavailable?:\n | ((stageId: string) => Promise<void>)\n | undefined;\n readonly stageId: string;\n}): Promise<void> {\n const request = {\n method: \"GET\" as const,\n path: multipartStagePath(input.stageId),\n };\n const failure = input.apiClient.getRequestFailure?.(request);\n if (!provesMultipartStageReplacement(failure)) {\n throw new Error(\n multipartApiFailureMessage({\n apiClient: input.apiClient,\n fallback: `Multipart blob resume stage lookup failed for stage ${input.stageId}.`,\n request,\n }),\n );\n }\n if (input.onStageUnavailable) {\n await input.onStageUnavailable(input.stageId);\n throw new Error(\n \"Multipart stage is unavailable; upload attempt stopped for recovery.\",\n );\n }\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"multipartStageResolution.js","sourceRoot":"","sources":["multipartStageResolution.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n InitiateMultipartBlobStageResponse,\n MultipartBlobStageStatusResponse,\n} from \"@tearleads/validators/response\";\nimport type { BlobEncryptionPlan } from \"../../data/documents/blob/shared/crypto\";\nimport type {\n BlobAttachmentApi,\n UploadDocumentAttachmentInput,\n} from \"../../data/documents/blob/shared/types\";\nimport {\n type MultipartFirstParts,\n type MultipartPartSources,\n type PreparedFirstPart,\n prepareFirstMultipartParts,\n readIssuedPartSources,\n releasePreparedParts,\n} from \"./multipartFirstParts\";\nimport {\n assertMultipartStageReplaceable,\n multipartApiFailureMessage,\n} from \"./multipartStageFailures\";\n\nfunction isMultipartStageStatus(\n stage: InitiateMultipartBlobStageResponse | MultipartBlobStageStatusResponse,\n): stage is MultipartBlobStageStatusResponse {\n return \"completed\" in stage && typeof stage.completed === \"boolean\";\n}\n\ninterface ResolveMultipartStageInput {\n readonly apiClient: BlobAttachmentApi;\n readonly concurrency: number;\n readonly encryption: BlobEncryptionPlan;\n readonly multipart: NonNullable<UploadDocumentAttachmentInput[\"multipart\"]>;\n readonly organizationId: string;\n readonly onStageUnavailable?:\n | ((stageId: string) => Promise<void>)\n | undefined;\n}\n\ninterface ResolvedMultipartStage {\n readonly prepared: Map<number, PreparedFirstPart>;\n readonly sources: MultipartPartSources;\n readonly status: MultipartBlobStageStatusResponse;\n}\n\nasync function resumeMultipartStage(\n input: ResolveMultipartStageInput,\n resumeStageId: string,\n): Promise<MultipartBlobStageStatusResponse | null> {\n const resumed = await input.apiClient.getMultipartBlobStage(resumeStageId);\n if (!resumed) {\n await assertMultipartStageReplaceable({\n apiClient: input.apiClient,\n onStageUnavailable: input.onStageUnavailable,\n stageId: resumeStageId,\n });\n return null;\n }\n if (resumed.stageId !== resumeStageId) {\n throw new Error(\n `Multipart blob resume response does not match stage ${resumeStageId}.`,\n );\n }\n // A successful lookup is authoritative: a metadata mismatch indicates\n // inconsistent persisted state or a bad server response, not proof that\n // the existing stage is safe to abandon.\n if (\n resumed.organizationId !== input.organizationId ||\n resumed.byteLength !== input.encryption.byteLength ||\n resumed.sha256 !== input.encryption.sha256\n ) {\n throw new Error(\n `Multipart blob resume stage ${resumeStageId} does not match the requested organization or bytes.`,\n );\n }\n return resumed;\n}\n\nasync function initiateWithFirstParts(\n input: ResolveMultipartStageInput,\n firstParts: MultipartFirstParts,\n): Promise<ResolvedMultipartStage> {\n const { byteLength, sha256 } = input.encryption;\n const stage = await input.apiClient.initiateMultipartBlobStage({\n organizationId: input.organizationId,\n byteLength,\n firstParts: [...firstParts.descriptors],\n sha256,\n });\n if (!stage) {\n throw new Error(\n multipartApiFailureMessage({\n apiClient: input.apiClient,\n fallback: `Multipart blob stage initiation failed for ${byteLength.toLocaleString()} bytes.`,\n request: { method: \"POST\", path: \"/blobs/stages/multipart\" },\n }),\n );\n }\n if (\n stage.organizationId !== input.organizationId ||\n stage.byteLength !== byteLength ||\n stage.sha256 !== sha256\n ) {\n throw new Error(\n \"Multipart blob stage initiation response does not match its request.\",\n );\n }\n return {\n prepared: firstParts.prepared,\n sources: readIssuedPartSources(firstParts.descriptors, stage),\n status: isMultipartStageStatus(stage)\n ? stage\n : { ...stage, completed: false },\n };\n}\n\n// A new stage carries the parts the upload starts with, so their upload\n// sources come back with the stage instead of one authorization each. Their\n// bytes hold transfer-pool slots until uploaded, or until initiation fails.\nasync function initiateMultipartStage(\n input: ResolveMultipartStageInput,\n): Promise<ResolvedMultipartStage> {\n const firstParts = await prepareFirstMultipartParts(\n input.apiClient,\n input.encryption,\n input.concurrency,\n );\n try {\n return await initiateWithFirstParts(input, firstParts);\n } catch (error) {\n releasePreparedParts(firstParts.prepared);\n throw error;\n }\n}\n\nexport async function resolveMultipartStage(\n input: ResolveMultipartStageInput,\n): Promise<ResolvedMultipartStage> {\n const resumeStageId = input.multipart.resumeStageId;\n const resumed = resumeStageId\n ? await resumeMultipartStage(input, resumeStageId)\n : null;\n return resumed\n ? {\n prepared: new Map(),\n sources: { apiTransport: false, issued: new Map() },\n status: resumed,\n }\n : initiateMultipartStage(input);\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"multipartUpload.js","sourceRoot":"","sources":["multipartUpload.ts"],"names":[],"mappings":"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","sourcesContent":["import { MAX_BLOB_CHUNK_COUNT } from \"@tearleads/crypto\";\nimport type { MultipartBlobStagePart } from \"@tearleads/validators/response\";\nimport { MAX_MULTIPART_BLOB_PART_BYTES } from \"@tearleads/validators/util\";\nimport {\n BLOB_TRANSFER_CONCURRENCY,\n runBlobTransfer,\n} from \"../../data/blobs/transferPool\";\nimport type { BlobEncryptionPlan } from \"../../data/documents/blob/shared/crypto\";\nimport type {\n BlobAttachmentApi,\n MultipartStageResolvedListener,\n MultipartUploadProgressListener,\n UploadDocumentAttachmentInput,\n} from \"../../data/documents/blob/shared/types\";\nimport {\n type MultipartPartSources,\n type PreparedFirstPart,\n type PreparedMultipartPart,\n releasePreparedParts,\n sha256BytesHex,\n takePartSource,\n} from \"./multipartFirstParts\";\nimport {\n multipartApiFailureMessage,\n multipartStagePath,\n} from \"./multipartStageFailures\";\nimport { resolveMultipartStage } from \"./multipartStageResolution\";\n\nconst DEFAULT_MULTIPART_UPLOAD_CONCURRENCY = 4;\nconst MAX_MULTIPART_UPLOAD_CONCURRENCY = 4;\n// Fetch exposes no upload progress on every host. Allow a slow shared uplink\n// (8 KiB/s total, shared by every admitted part), plus setup/encryption time.\nconst MULTIPART_TRANSFER_BYTES_PER_SECOND = 8 * 1024;\n\ninterface MultipartPartCommit {\n readonly etag: string;\n readonly partNumber: number;\n}\n\ninterface MultipartPartUploadTask {\n readonly byteLength: number;\n readonly partIndex: number;\n readonly partNumber: number;\n}\n\nfunction pathSegment(value: number | string): string {\n return encodeURIComponent(String(value));\n}\n\nfunction multipartPartRequest(input: {\n readonly apiClient: BlobAttachmentApi;\n readonly partNumber: number;\n readonly stageId: string;\n}) {\n const basePath = `${multipartStagePath(input.stageId)}/parts/${pathSegment(input.partNumber)}`;\n const authorization = { method: \"POST\" as const, path: `${basePath}/upload` };\n // A successful authorization clears its previous failure. If a memory-store\n // byte request then fails, its separate transport diagnostic is authoritative.\n return input.apiClient.getRequestFailure?.(authorization)\n ? authorization\n : { method: \"PUT\" as const, path: `${basePath}/bytes` };\n}\n\nfunction normalizeMultipartUploadConcurrency(\n value: number | undefined,\n): number {\n if (value === undefined) {\n return DEFAULT_MULTIPART_UPLOAD_CONCURRENCY;\n }\n if (\n !Number.isInteger(value) ||\n value <= 0 ||\n value > MAX_MULTIPART_UPLOAD_CONCURRENCY\n ) {\n throw new Error(\n `Multipart blob upload concurrency must be between 1 and ${MAX_MULTIPART_UPLOAD_CONCURRENCY}`,\n );\n }\n\n return value;\n}\n\nfunction isMultipartPartCommit(\n part: MultipartPartCommit | undefined,\n): part is MultipartPartCommit {\n return part !== undefined;\n}\n\nasync function uploadMultipartPartTasks(input: {\n readonly apiClient: BlobAttachmentApi;\n readonly completeParts: (MultipartPartCommit | undefined)[];\n readonly concurrency: number;\n readonly encryption: BlobEncryptionPlan;\n readonly onPartUploaded?: (task: MultipartPartUploadTask) => void;\n readonly prepared: Map<number, PreparedFirstPart>;\n readonly sources: MultipartPartSources;\n readonly stageId: string;\n readonly tasks: readonly MultipartPartUploadTask[];\n readonly uploadId: string;\n}): Promise<void> {\n let failed = false;\n let firstFailure: { readonly error: unknown } | undefined;\n let nextTaskIndex = 0;\n const recordFailure = (error: unknown) => {\n failed = true;\n firstFailure ??= { error };\n };\n\n async function worker(): Promise<void> {\n while (!failed) {\n const task = input.tasks[nextTaskIndex];\n nextTaskIndex += 1;\n if (!task) {\n return;\n }\n\n try {\n // A first part already holds the pool slot its prepared bytes use.\n const heldPermit = input.prepared.get(task.partIndex)?.permit;\n await runBlobTransfer(\n input.apiClient,\n async (signal) => {\n if (failed) return;\n const aborted = () => recordFailure(signal.reason);\n signal.addEventListener(\"abort\", aborted, { once: true });\n try {\n const uploaded = await uploadMultipartPartBytes({\n apiClient: input.apiClient,\n encryption: input.encryption,\n prepared: input.prepared,\n sources: input.sources,\n stageId: input.stageId,\n task,\n uploadId: input.uploadId,\n signal,\n });\n signal.throwIfAborted();\n if (!uploaded) {\n failed = true;\n throw new Error(\n multipartApiFailureMessage({\n apiClient: input.apiClient,\n fallback: `Multipart blob part ${task.partNumber} upload failed for stage ${input.stageId}.`,\n request: multipartPartRequest({\n apiClient: input.apiClient,\n partNumber: task.partNumber,\n stageId: input.stageId,\n }),\n }),\n );\n }\n\n input.completeParts[task.partIndex] = {\n etag: uploaded.part.etag,\n partNumber: task.partNumber,\n };\n input.onPartUploaded?.(task);\n } catch (error) {\n // Publish failure before releasing the permit to a queued sibling.\n // Already-started parts still record success and drain through the join.\n recordFailure(error);\n } finally {\n signal.removeEventListener(\"abort\", aborted);\n }\n },\n 120_000 +\n Math.ceil(\n (task.byteLength * BLOB_TRANSFER_CONCURRENCY * 1000) /\n MULTIPART_TRANSFER_BYTES_PER_SECOND,\n ),\n heldPermit,\n );\n } catch (error) {\n recordFailure(error);\n }\n }\n }\n\n const workerCount = Math.min(input.concurrency, input.tasks.length);\n await Promise.all(Array.from({ length: workerCount }, () => worker()));\n if (firstFailure) {\n throw firstFailure.error;\n }\n}\n\n// A first part was encrypted once before the stage existed; hand its bytes\n// over (and release them) instead of encrypting it again.\nasync function encryptedPart(input: {\n readonly encryption: BlobEncryptionPlan;\n readonly prepared: Map<number, PreparedFirstPart>;\n readonly task: MultipartPartUploadTask;\n}): Promise<PreparedMultipartPart> {\n const prepared = input.prepared.get(input.task.partIndex);\n if (prepared) {\n input.prepared.delete(input.task.partIndex);\n return prepared;\n }\n const bytes = await input.encryption.encryptPart(input.task.partIndex);\n if (bytes.byteLength !== input.task.byteLength) {\n throw new Error(\n `Encrypted blob part ${input.task.partNumber} byte length mismatch: expected ${input.task.byteLength.toLocaleString()}, received ${bytes.byteLength.toLocaleString()}.`,\n );\n }\n return { bytes, sha256: await sha256BytesHex(bytes) };\n}\n\nasync function uploadMultipartPartBytes(input: {\n readonly apiClient: BlobAttachmentApi;\n readonly encryption: BlobEncryptionPlan;\n readonly prepared: Map<number, PreparedFirstPart>;\n readonly sources: MultipartPartSources;\n readonly stageId: string;\n readonly task: MultipartPartUploadTask;\n readonly uploadId: string;\n readonly signal: AbortSignal;\n}): ReturnType<BlobAttachmentApi[\"uploadMultipartBlobPartBytes\"]> {\n input.signal.throwIfAborted();\n const { bytes: encryptedPartBytes, sha256 } = await encryptedPart(input);\n input.signal.throwIfAborted();\n const source = takePartSource(input.sources, input.task.partNumber);\n const uploaded = await input.apiClient.uploadMultipartBlobPartBytes(\n input.stageId,\n input.task.partNumber,\n {\n byteLength: encryptedPartBytes.byteLength,\n encryptedBytes: encryptedPartBytes,\n sha256,\n ...(source === undefined ? {} : { source }),\n uploadId: input.uploadId,\n },\n { signal: input.signal },\n );\n input.signal.throwIfAborted();\n if (\n uploaded &&\n (uploaded.stageId !== input.stageId ||\n uploaded.uploadId !== input.uploadId ||\n uploaded.part.partNumber !== input.task.partNumber ||\n uploaded.part.byteLength !== input.task.byteLength)\n ) {\n throw new Error(\n `Multipart blob part ${input.task.partNumber} response does not match its request.`,\n );\n }\n return uploaded;\n}\n\nfunction uploadedPartsByPartNumber(\n parts: readonly MultipartBlobStagePart[],\n): ReadonlyMap<number, MultipartBlobStagePart> {\n return new Map(parts.map((part) => [part.partNumber, part]));\n}\n\ninterface MultipartUploadProgressState {\n bytesTotal: number;\n bytesUploaded: number;\n partsCompleted: number;\n partsTotal: number;\n}\n\ninterface MultipartPartPlan {\n completeParts: (MultipartPartCommit | undefined)[];\n progress: MultipartUploadProgressState;\n uploadTasks: MultipartPartUploadTask[];\n}\n\n/**\n * Plans encrypted part indices without materializing their bytes, reusing any\n * already-staged parts and seeding cumulative progress for resumed uploads.\n */\nfunction planMultipartParts(input: {\n encryption: BlobEncryptionPlan;\n uploadedParts: ReadonlyMap<number, MultipartBlobStagePart>;\n}): MultipartPartPlan {\n const { encryption, uploadedParts } = input;\n const completeParts: (MultipartPartCommit | undefined)[] = new Array(\n encryption.partCount,\n );\n const uploadTasks: MultipartPartUploadTask[] = [];\n const progress: MultipartUploadProgressState = {\n bytesTotal: 0,\n bytesUploaded: 0,\n partsCompleted: 0,\n partsTotal: encryption.partCount,\n };\n\n for (let partIndex = 0; partIndex < encryption.partCount; partIndex += 1) {\n const partNumber = partIndex + 1;\n const byteLength = encryption.getPartByteLength(partIndex);\n progress.bytesTotal += byteLength;\n const uploadedPart = uploadedParts.get(partNumber);\n if (uploadedPart?.byteLength === byteLength) {\n completeParts[partIndex] = {\n etag: uploadedPart.etag,\n partNumber,\n };\n progress.partsCompleted += 1;\n progress.bytesUploaded += byteLength;\n continue;\n }\n\n uploadTasks.push({\n byteLength,\n partIndex,\n partNumber,\n });\n }\n\n return { completeParts, progress, uploadTasks };\n}\n\nfunction assertMultipartPlanLimits(encryption: BlobEncryptionPlan): void {\n if (encryption.partCount > MAX_BLOB_CHUNK_COUNT) {\n throw new Error(\n `Multipart blob upload would require ${encryption.partCount.toLocaleString()} parts; the maximum is ${MAX_BLOB_CHUNK_COUNT.toLocaleString()} parts.`,\n );\n }\n for (let index = 0; index < encryption.partCount; index += 1) {\n if (encryption.getPartByteLength(index) > MAX_MULTIPART_BLOB_PART_BYTES) {\n throw new Error(\n `Encrypted blob part ${index + 1} exceeds the 32 MiB multipart part limit.`,\n );\n }\n }\n}\n\ntype StageMultipartBlobAttachmentInput = {\n readonly apiClient: BlobAttachmentApi;\n readonly encryption: BlobEncryptionPlan;\n readonly multipart: NonNullable<UploadDocumentAttachmentInput[\"multipart\"]>;\n readonly organizationId: string;\n readonly onMultipartProgress?: MultipartUploadProgressListener | undefined;\n readonly onStageResolved?: MultipartStageResolvedListener | undefined;\n readonly onStageUnavailable?:\n | ((stageId: string) => Promise<void>)\n | undefined;\n};\n\nexport async function stageMultipartBlobAttachment(\n input: StageMultipartBlobAttachmentInput,\n): Promise<string | null> {\n if (input.multipart.partSize !== input.encryption.chunkSize) {\n throw new Error(\n \"Multipart part size must match the encryption chunk size exactly.\",\n );\n }\n assertMultipartPlanLimits(input.encryption);\n const concurrency = normalizeMultipartUploadConcurrency(\n input.multipart.uploadConcurrency,\n );\n const resolved = await resolveMultipartStage({\n apiClient: input.apiClient,\n concurrency,\n encryption: input.encryption,\n multipart: input.multipart,\n organizationId: input.organizationId,\n onStageUnavailable: input.onStageUnavailable,\n });\n try {\n return await uploadResolvedMultipartStage(input, concurrency, resolved);\n } finally {\n // First parts no worker consumed (an early failure) return their slots.\n releasePreparedParts(resolved.prepared);\n }\n}\n\nasync function uploadResolvedMultipartStage(\n input: StageMultipartBlobAttachmentInput,\n concurrency: number,\n {\n prepared,\n sources,\n status,\n }: Awaited<ReturnType<typeof resolveMultipartStage>>,\n): Promise<string> {\n // Surface the stage id before any parts upload so the caller can persist it;\n // an upload interrupted mid-flight can then resume this same stage.\n await input.onStageResolved?.({\n partSize: input.encryption.chunkSize,\n stageId: status.stageId,\n });\n if (status.completed) {\n input.onMultipartProgress?.({\n bytesTotal: input.encryption.byteLength,\n bytesUploaded: input.encryption.byteLength,\n partsCompleted: input.encryption.partCount,\n partsTotal: input.encryption.partCount,\n });\n return status.stageId;\n }\n\n const { completeParts, progress, uploadTasks } = planMultipartParts({\n encryption: input.encryption,\n uploadedParts: uploadedPartsByPartNumber(status.uploadedParts),\n });\n\n const reportMultipartProgress = () => {\n input.onMultipartProgress?.({\n bytesTotal: progress.bytesTotal,\n bytesUploaded: progress.bytesUploaded,\n partsCompleted: progress.partsCompleted,\n partsTotal: progress.partsTotal,\n });\n };\n reportMultipartProgress();\n\n await uploadMultipartPartTasks({\n apiClient: input.apiClient,\n completeParts,\n concurrency,\n encryption: input.encryption,\n onPartUploaded: (task) => {\n progress.partsCompleted += 1;\n progress.bytesUploaded += task.byteLength;\n reportMultipartProgress();\n },\n prepared,\n sources,\n stageId: status.stageId,\n tasks: uploadTasks,\n uploadId: status.uploadId,\n });\n const committedParts = completeParts.filter(isMultipartPartCommit);\n if (committedParts.length !== input.encryption.partCount) {\n throw new Error(\n `Multipart blob upload incomplete for stage ${status.stageId}: committed ${committedParts.length.toLocaleString()} of ${input.encryption.partCount.toLocaleString()} parts.`,\n );\n }\n\n // Binding the attachment completes the stage: the API assembles these parts\n // and verifies the object's length and SHA-256 before promoting it.\n return status.stageId;\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"retainedAttachmentVerification.js","sourceRoot":"","sources":["retainedAttachmentVerification.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,EAAE,oCAAoC,EAAE,MAAM,4CAA4C,CAAC;AAElG,OAAO,EAAE,wCAAwC,EAAE,MAAM,wCAAwC,CAAC;AAClG,OAAO,EAAE,6BAA6B,EAAE,MAAM,mCAAmC,CAAC;AAClF,OAAO,EAEL,gCAAgC,GACjC,MAAM,yCAAyC,CAAC;AACjD,OAAO,EAAE,+BAA+B,EAAE,MAAM,iCAAiC,CAAC;AAClF,OAAO,EAAE,2BAA2B,EAAE,MAAM,qBAAqB,CAAC;AAElE,kFAAkF;AAClF,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAC5C,KAGC;IAED,MAAM,wBAAwB,GAAG,gCAAgC,CAC/D,KAAK,CAAC,wBAAwB,EAC9B,2BAA2B,CAC5B,CAAC;IACF,IAAI,aAAgE,CAAC;IACrE,MAAM,wCAAwC,CAAC,KAAK,CAAC,gBAAgB,EAAE;QACrE,0BAA0B,EAAE,IAAI;QAChC,GAAG,6BAA6B,CAAC;YAC/B,OAAO,EAAE,KAAK,CAAC,OAAO;YACtB,YAAY,EAAE,KAAK,CAAC,YAAY;YAChC,+BAA+B,EAAE,KAAK,CAAC,+BAA+B;YACtE,wBAAwB;SACzB,CAAC;QACF,uBAAuB,EAAE,CAAC,KAAK,EAAE,EAAE;YACjC,aAAa,GAAG,KAAK,CAAC;QACxB,CAAC;KACF,CAAC,CAAC;IACH,IAAI,KAAK,CAAC,OAAO,CAAC,gBAAgB,CAAC,MAAM,KAAK,KAAK,CAAC,OAAO,CAAC,MAAM;QAChE,MAAM,IAAI,uBAAuB,CAC/B,iBAAiB,EACjB,+CAA+C,CAChD,CAAC;IACJ,MAAM,oCAAoC,CAAC,KAAK,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC;IAC3E,MAAM,+BAA+B,CAAC;QACpC,GAAG,KAAK;QACR,aAAa;QACb,wBAAwB;KACzB,CAAC,CAAC;IACH,IAAI,CAAC,aAAa;QAAE,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC;IAC3E,2BAA2B,CAAC;QAC1B,aAAa;QACb,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,UAAU,EAAE,KAAK,CAAC,kBAAkB;KACrC,CAAC,CAAC;AACL,CAAC","sourcesContent":["import { KeyingVerificationError } from \"@tearleads/crypto\";\nimport { assertBlobContentKeyBundleTargetHash } from \"../../data/documents/blob/shared/responses\";\nimport type { DecryptDocumentAttachmentBlobInput } from \"../../data/documents/blob/shared/types\";\nimport { assertDocumentWriterProjectionConsistent } from \"../../data/documents/shared/projection\";\nimport { projectionVerificationOptions } from \"../../data/documents/shared/types\";\nimport {\n type DocumentWriterProjectionAuthorization,\n requireProjectionUserKeyResolver,\n} from \"../../data/keyingProjectionVerification\";\nimport { assertAttachmentBindingVerified } from \"./attachmentBindingVerification\";\nimport { assertBlobWrapScopeVerified } from \"./verifiedWrapScope\";\n\n/** Retaining an existing envelope does not propagate a key to a new recipient. */\nexport async function verifyRetainedAttachment(\n input: Omit<\n DecryptDocumentAttachmentBlobInput,\n \"encryptedBytes\" | \"targetSecretKey\"\n >,\n): Promise<void> {\n const resolveProjectionUserKey = requireProjectionUserKeyResolver(\n input.resolveProjectionUserKey,\n \"Retained attachment scope\",\n );\n let authorization: DocumentWriterProjectionAuthorization | undefined;\n await assertDocumentWriterProjectionConsistent(input.writerProjection, {\n allowStaleContentKeyBundle: true,\n ...projectionVerificationOptions({\n execSql: input.execSql,\n stillCurrent: input.stillCurrent,\n warmReferencedPrincipalPolicies: input.warmReferencedPrincipalPolicies,\n resolveProjectionUserKey,\n }),\n onVerifiedAuthorization: (value) => {\n authorization = value;\n },\n });\n if (input.binding.contentKeyBundle.blobId !== input.binding.blobId)\n throw new KeyingVerificationError(\n \"object_mismatch\",\n \"Retained attachment bundle names another blob\",\n );\n await assertBlobContentKeyBundleTargetHash(input.binding.contentKeyBundle);\n await assertAttachmentBindingVerified({\n ...input,\n authorization,\n resolveProjectionUserKey,\n });\n if (!authorization) throw new Error(\"Attachment authority is unavailable\");\n assertBlobWrapScopeVerified({\n authorization,\n binding: input.binding,\n documentId: input.expectedDocumentId,\n });\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"upload.js","sourceRoot":"","sources":["upload.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n AccessEvent,\n AttachmentBindAccessEventBody,\n WriteHeader,\n} from \"@tearleads/crypto\";\nimport {\n computeBlobAccessManifestHash,\n computeBlobContentKeyTargetHash,\n} from \"@tearleads/crypto\";\nimport type {\n BlobAttachmentBindRequest,\n BlobContentKeyBundleRequest,\n} from \"@tearleads/validators/request\";\nimport type { BlobAttachmentBindResponse } from \"@tearleads/validators/response\";\nimport {\n type BlobByteSource,\n createBlobByteSource,\n} from \"../../data/blobs/blobContracts\";\nimport type { BlobSourceSnapshot } from \"../../data/documents/blob/shared/blobSourceSnapshot\";\nimport { prepareBlobEncryption } from \"../../data/documents/blob/shared/crypto\";\nimport {\n signBlobAttachmentEvent,\n signBlobAttachmentWriteHeader,\n} from \"../../data/documents/blob/shared/events\";\nimport {\n verifiedBlobWrapTargetsFromDocumentProjection,\n wrapBlobContentKey,\n} from \"../../data/documents/blob/shared/projection\";\nimport { assertBlobAttachmentBindResponse } from \"../../data/documents/blob/shared/responses\";\nimport type {\n BlobAttachmentApi,\n BlobAttachmentMaterial,\n MultipartStageResolvedListener,\n MultipartUploadProgressListener,\n UploadDocumentAttachmentInput,\n UploadDocumentAttachmentResult,\n} from \"../../data/documents/blob/shared/types\";\nimport { authorizingContainerPathRefs } from \"../../data/documents/shared/projection\";\nimport { uniqueSortedStrings } from \"../../data/documents/shared/readers\";\nimport {\n type DocumentCreateAuthor,\n type ProjectionVerificationOptions,\n projectionVerificationOptions,\n} from \"../../data/documents/shared/types\";\nimport { readCanonicalRecord } from \"../../data/keying/canonicalJson\";\nimport { requireProjectionUserKeyResolver } from \"../../data/keyingProjectionVerification\";\nimport type { ExecSql } from \"../../data/sqlite/sqlSchema\";\nimport { shouldRetryWithFreshProjection } from \"../documents/syncFailureClassification\";\nimport { resolveMultipartUploadOptions } from \"./automaticMultipartUpload\";\nimport { stageMultipartBlobAttachment } from \"./multipartUpload\";\nimport { resolveBlobMutationWriterProjection } from \"./writerProjection\";\n\nasync function buildBlobAttachmentMaterial(\n input: {\n apiClient: BlobAttachmentApi;\n bindingId: string;\n blobId: string;\n contentKey: Uint8Array;\n contentKeyEpoch: number;\n documentId: string;\n execSql?: ExecSql | undefined;\n isRemoteSyncBlocked?: ((organizationId: string) => boolean) | undefined;\n nonceSeed?: Uint8Array | undefined;\n partSize: number;\n source: BlobByteSource;\n sourceSnapshot?: BlobSourceSnapshot | undefined;\n targetSecretKey: Uint8Array;\n writerProjection?: UploadDocumentAttachmentInput[\"writerProjection\"];\n } & ProjectionVerificationOptions,\n): Promise<BlobAttachmentMaterial | null> {\n const resolved = await resolveBlobMutationWriterProjection({\n apiClient: input.apiClient,\n documentId: input.documentId,\n errorLabel: \"Blob attachment\",\n execSql: input.execSql,\n isRemoteSyncBlocked: input.isRemoteSyncBlocked,\n writerProjection: input.writerProjection,\n ...projectionVerificationOptions(input),\n });\n if (!resolved) {\n return null;\n }\n const { manifestIdentity, writerProjection } = resolved;\n\n const targets = verifiedBlobWrapTargetsFromDocumentProjection({\n bindingId: input.bindingId,\n documentId: input.documentId,\n writerProjection,\n });\n const targetHash = await computeBlobContentKeyTargetHash(targets);\n const contentKeyBundle: BlobContentKeyBundleRequest = {\n contentKeyEpoch: input.contentKeyEpoch,\n targetHash,\n targets: await wrapBlobContentKey({\n blobId: input.blobId,\n contentKey: input.contentKey,\n contentKeyEpoch: input.contentKeyEpoch,\n execSql: input.execSql,\n secretKey: input.targetSecretKey,\n targets,\n writerProjection,\n ...projectionVerificationOptions(input),\n }),\n };\n const encrypted = await prepareBlobEncryption({\n blobId: input.blobId,\n chunkSize: input.partSize,\n contentKey: input.contentKey,\n contentKeyBundle,\n nonceSeed: input.nonceSeed,\n organizationId: manifestIdentity.organizationId,\n source: input.source,\n sourceSnapshot: input.sourceSnapshot,\n });\n const blobAccessManifestHash = await computeBlobAccessManifestHash({\n version: 1,\n blobId: input.blobId,\n organizationId: manifestIdentity.organizationId,\n activeBindingIds: [input.bindingId],\n documentManifestHashes: [manifestIdentity.manifestHash],\n linkedContainerManifestHashes: uniqueSortedStrings(\n targets.map((target) => target.containerManifestHash),\n ),\n linkedContainerKeyEpochIds: uniqueSortedStrings(\n targets.map((target) => target.containerKeyEpochId),\n ),\n blobKeyTargetHash: targetHash,\n });\n\n return {\n blobAccessManifestHash,\n contentKeyBundle,\n encrypted,\n manifestIdentity,\n targetHash,\n targets,\n writerProjection,\n };\n}\n\nfunction blobAttachmentBindRequest(input: {\n body: AttachmentBindAccessEventBody;\n event: AccessEvent;\n material: BlobAttachmentMaterial;\n stageId: string;\n writeHeader: WriteHeader;\n}): BlobAttachmentBindRequest {\n return {\n event: readCanonicalRecord(input.event, \"Blob attachment bind event\"),\n body: readCanonicalRecord(input.body, \"Blob attachment bind body\"),\n authorizingContainerPathRefs: authorizingContainerPathRefs(\n input.material.writerProjection,\n ),\n contentKeyBundle: input.material.contentKeyBundle,\n stagedBlob: {\n stageId: input.stageId,\n writeHeader: readCanonicalRecord(\n input.writeHeader,\n \"Blob attachment write header\",\n ),\n },\n };\n}\n\nasync function stageAndBindBlobAttachment(input: {\n apiClient: BlobAttachmentApi;\n author: DocumentCreateAuthor;\n bindingId: string;\n blobId: string;\n contentKeyEpoch: number;\n documentId: string;\n eventId: string;\n expectedBindingId: string | null;\n material: BlobAttachmentMaterial;\n multipart: NonNullable<UploadDocumentAttachmentInput[\"multipart\"]>;\n onMultipartProgress?: MultipartUploadProgressListener | undefined;\n onStageResolved?: MultipartStageResolvedListener | undefined;\n onStageUnavailable?: ((stageId: string) => Promise<void>) | undefined;\n signedAt: string;\n slotId: string;\n}): Promise<{\n request: BlobAttachmentBindRequest;\n response: BlobAttachmentBindResponse;\n sha256: string;\n byteLength: number;\n writeHeader: WriteHeader;\n writeHeaderHash: string;\n} | null> {\n const { body, event } = await signBlobAttachmentEvent({\n author: input.author,\n bindingId: input.bindingId,\n blobId: input.blobId,\n documentId: input.documentId,\n eventId: input.eventId,\n expectedBindingId: input.expectedBindingId,\n manifestIdentity: input.material.manifestIdentity,\n signedAt: input.signedAt,\n slotId: input.slotId,\n authorizingContainerPathRefs: authorizingContainerPathRefs(\n input.material.writerProjection,\n ),\n });\n const { writeHeader, writeHeaderHash } = await signBlobAttachmentWriteHeader({\n authorizingContainerPathRefs: authorizingContainerPathRefs(\n input.material.writerProjection,\n ),\n author: input.author,\n blobAccessManifestHash: input.material.blobAccessManifestHash,\n blobId: input.blobId,\n contentKeyEpoch: input.contentKeyEpoch,\n encrypted: input.material.encrypted,\n manifestIdentity: input.material.manifestIdentity,\n signedAt: input.signedAt,\n targetHash: input.material.targetHash,\n });\n const stageId = await stageMultipartBlobAttachment({\n organizationId: input.material.manifestIdentity.organizationId,\n apiClient: input.apiClient,\n encryption: input.material.encrypted,\n multipart: input.multipart,\n onMultipartProgress: input.onMultipartProgress,\n onStageResolved: input.onStageResolved,\n onStageUnavailable: input.onStageUnavailable,\n });\n if (!stageId) {\n return null;\n }\n\n const request = blobAttachmentBindRequest({\n body,\n event,\n material: input.material,\n stageId,\n writeHeader,\n });\n const response = await input.apiClient.bindBlobAttachment(\n input.blobId,\n request,\n {\n expectedPaymentRequiredOrganizationId:\n input.material.manifestIdentity.organizationId,\n },\n );\n if (!response) {\n return null;\n }\n\n await assertBlobAttachmentBindResponse({\n body,\n bindingId: input.bindingId,\n blobAccessManifestHash: input.material.blobAccessManifestHash,\n blobId: input.blobId,\n contentKeyBundle: input.material.contentKeyBundle,\n documentId: input.documentId,\n event,\n manifestIdentity: input.material.manifestIdentity,\n response,\n slotId: input.slotId,\n targetHash: input.material.targetHash,\n targets: input.material.targets,\n writeHeader,\n writeHeaderHash,\n });\n\n return {\n request,\n response,\n sha256: input.material.encrypted.sha256,\n byteLength: input.material.encrypted.byteLength,\n writeHeader,\n writeHeaderHash,\n };\n}\n\ninterface PreparedUploadDocumentAttachmentInput\n extends UploadDocumentAttachmentInput {\n readonly sourceSnapshot?: BlobSourceSnapshot | undefined;\n readonly onStageUnavailable?:\n | ((stageId: string) => Promise<void>)\n | undefined;\n}\n\nasync function uploadDocumentAttachmentImpl({\n apiClient,\n author,\n blobId = crypto.randomUUID(),\n bindingId = crypto.randomUUID(),\n bytes,\n contentKey = crypto.getRandomValues(new Uint8Array(32)),\n contentKeyEpoch = 1,\n documentId,\n eventId = crypto.randomUUID(),\n execSql,\n expectedBindingId,\n isRemoteSyncBlocked,\n nonceSeed,\n multipart,\n onMultipartProgress,\n onStageResolved,\n onStageUnavailable,\n resolveProjectionUserKey,\n signedAt = new Date().toISOString(),\n slotId,\n sourceSnapshot,\n targetSecretKey,\n warmReferencedPrincipalPolicies,\n writerProjection,\n}: PreparedUploadDocumentAttachmentInput): Promise<UploadDocumentAttachmentResult | null> {\n if (contentKey.byteLength !== 32) {\n throw new Error(\"Blob content key must be 32 bytes\");\n }\n const resolveProjectionUserKeyForUpload = requireProjectionUserKeyResolver(\n resolveProjectionUserKey,\n \"Document attachment upload\",\n );\n const resolvedMultipart = resolveMultipartUploadOptions(multipart);\n const source = createBlobByteSource(bytes);\n\n const buildMaterial = (\n freshWriterProjection: UploadDocumentAttachmentInput[\"writerProjection\"],\n ) =>\n buildBlobAttachmentMaterial({\n apiClient,\n bindingId,\n blobId,\n contentKey,\n contentKeyEpoch,\n documentId,\n execSql,\n isRemoteSyncBlocked,\n nonceSeed,\n partSize: resolvedMultipart.partSize,\n resolveProjectionUserKey: resolveProjectionUserKeyForUpload,\n source,\n sourceSnapshot,\n targetSecretKey,\n warmReferencedPrincipalPolicies,\n writerProjection: freshWriterProjection,\n });\n let material: BlobAttachmentMaterial | null;\n try {\n material = await buildMaterial(writerProjection);\n } catch (error) {\n if (\n !apiClient.evictDocumentWriterProjection ||\n !shouldRetryWithFreshProjection(\n error,\n (message) =>\n message.startsWith(\"Container writer projection KEK\") &&\n message.includes(\"could not be unwrapped\"),\n )\n ) {\n throw error;\n }\n\n // The attachment binds to this document; only its projection was stale, so\n // evict just it rather than wiping the whole projection cache.\n apiClient.evictDocumentWriterProjection(documentId);\n material = await buildMaterial(undefined);\n }\n if (!material) {\n return null;\n }\n const result = await stageAndBindBlobAttachment({\n apiClient,\n author,\n bindingId,\n blobId,\n contentKeyEpoch,\n documentId,\n eventId,\n expectedBindingId,\n material,\n multipart: resolvedMultipart,\n onMultipartProgress,\n onStageResolved,\n onStageUnavailable,\n signedAt,\n slotId,\n });\n if (!result) {\n return null;\n }\n\n return {\n blobId,\n bindingId,\n writerProjection: material.writerProjection,\n ...result,\n };\n}\n\nexport function uploadDocumentAttachment(\n input: UploadDocumentAttachmentInput,\n): Promise<UploadDocumentAttachmentResult | null> {\n return uploadDocumentAttachmentImpl({ ...input, sourceSnapshot: undefined });\n}\n\n/** Internal upload path for a source snapshot produced by `inspectBlobSource`. */\nexport function uploadPreparedDocumentAttachment(\n input: PreparedUploadDocumentAttachmentInput,\n): Promise<UploadDocumentAttachmentResult | null> {\n return uploadDocumentAttachmentImpl(input);\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"verifiedWrapScope.js","sourceRoot":"","sources":["verifiedWrapScope.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AAG5D,OAAO,EAAE,oCAAoC,EAAE,MAAM,+DAA+D,CAAC;AAErH,+EAA+E;AAC/E,MAAM,UAAU,2BAA2B,CAAC,KAI3C;IACC,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,gBAAgB,CAAC,OAAO,CAAC,MAAM,CAC3D,CAAC,MAAM,EAAE,EAAE,CACT,MAAM,CAAC,SAAS,KAAK,KAAK,CAAC,OAAO,CAAC,SAAS;QAC5C,MAAM,CAAC,UAAU,KAAK,KAAK,CAAC,UAAU,CACzC,CAAC;IACF,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QACtB,MAAM,IAAI,uBAAuB,CAC/B,iBAAiB,EACjB,yCAAyC,CAC1C,CAAC;IACJ,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,MAAM,IAAI,GAAG,KAAK,CAAC,aAAa,CAAC,2BAA2B,CAAC,GAAG,CAC9D,MAAM,CAAC,qBAAqB,CAC7B,CAAC;QACF,MAAM,QAAQ,GAAG,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QAC9B,IAAI,CAAC,QAAQ;YACX,MAAM,IAAI,oCAAoC,CAC5C,6CAA6C,CAC9C,CAAC;QACJ,IACE,QAAQ,CAAC,KAAK,CAAC,WAAW,KAAK,MAAM,CAAC,WAAW;YACjD,QAAQ,CAAC,KAAK,CAAC,mBAAmB,KAAK,MAAM,CAAC,mBAAmB,EACjE,CAAC;YACD,MAAM,IAAI,uBAAuB,CAC/B,iBAAiB,EACjB,6DAA6D,CAC9D,CAAC;QACJ,CAAC;IACH,CAAC;AACH,CAAC","sourcesContent":["import { KeyingVerificationError } from \"@tearleads/crypto\";\nimport type { BlobAttachmentSummary } from \"@tearleads/validators/response\";\nimport type { DocumentWriterProjectionAuthorization } from \"../../data/keyingProjectionVerification\";\nimport { ProjectionDependencyUnavailableError } from \"../../data/keyingProjectionVerification/dependencyUnavailable\";\n\n/** A retained wrap must name a KEK committed by verified container history. */\nexport function assertBlobWrapScopeVerified(input: {\n authorization: DocumentWriterProjectionAuthorization;\n binding: BlobAttachmentSummary;\n documentId: string;\n}): void {\n const targets = input.binding.contentKeyBundle.targets.filter(\n (target) =>\n target.bindingId === input.binding.bindingId &&\n target.documentId === input.documentId,\n );\n if (targets.length === 0)\n throw new KeyingVerificationError(\n \"object_mismatch\",\n \"Blob bundle lacks its attachment target\",\n );\n for (const target of targets) {\n const path = input.authorization.containerPathByManifestHash.get(\n target.containerManifestHash,\n );\n const manifest = path?.at(-1);\n if (!manifest)\n throw new ProjectionDependencyUnavailableError(\n \"Blob wrapped-target manifest is unavailable\",\n );\n if (\n manifest.state.containerId !== target.containerId ||\n manifest.state.containerKeyEpochId !== target.containerKeyEpochId\n ) {\n throw new KeyingVerificationError(\n \"object_mismatch\",\n \"Blob wrapped target differs from verified container history\",\n );\n }\n }\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"writerProjection.js","sourceRoot":"","sources":["writerProjection.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,4BAA4B,EAAE,MAAM,0CAA0C,CAAC;AAKxF,OAAO,EAAE,wCAAwC,EAAE,MAAM,wCAAwC,CAAC;AAClG,OAAO,EAEL,6BAA6B,GAC9B,MAAM,mCAAmC,CAAC;AAG3C;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,mCAAmC,CACvD,KAQiC;IAKjC,MAAM,gBAAgB,GACpB,KAAK,CAAC,gBAAgB;QACtB,CAAC,MAAM,KAAK,CAAC,SAAS,CAAC,2BAA2B,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC;IACxE,IAAI,CAAC,gBAAgB,EAAE,CAAC;QACtB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,wCAAwC,CAAC,gBAAgB,EAAE;QAC/D,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,GAAG,6BAA6B,CAAC,KAAK,CAAC;KACxC,CAAC,CAAC;IACH,MAAM,gBAAgB,GAAG,4BAA4B,CAAC,gBAAgB,CAAC,CAAC;IACxE,IAAI,gBAAgB,CAAC,UAAU,KAAK,KAAK,CAAC,UAAU,EAAE,CAAC;QACrD,MAAM,IAAI,KAAK,CACb,GAAG,KAAK,CAAC,UAAU,2CAA2C,CAC/D,CAAC;IACJ,CAAC;IACD,IAAI,KAAK,CAAC,mBAAmB,EAAE,CAAC,gBAAgB,CAAC,cAAc,CAAC,EAAE,CAAC;QACjE,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,CAAC;AAChD,CAAC","sourcesContent":["import type { DocumentWriterProjectionResponse } from \"@tearleads/validators/response\";\nimport { readDocumentManifestIdentity } from \"../../data/documents/blob/shared/readers\";\nimport type {\n BlobAttachmentApi,\n DocumentManifestIdentity,\n} from \"../../data/documents/blob/shared/types\";\nimport { assertDocumentWriterProjectionConsistent } from \"../../data/documents/shared/projection\";\nimport {\n type ProjectionVerificationOptions,\n projectionVerificationOptions,\n} from \"../../data/documents/shared/types\";\nimport type { ExecSql } from \"../../data/sqlite/sqlSchema\";\n\n/**\n * Shared prologue for blob attachment mutations (upload/detach): resolve the\n * document writer projection, verify its consistency, confirm it targets the\n * mutated document, and gate on a blocked organization. Returns null when the\n * projection is unavailable or the organization's remote sync is blocked.\n */\nexport async function resolveBlobMutationWriterProjection(\n input: {\n apiClient: Pick<BlobAttachmentApi, \"getDocumentWriterProjection\">;\n documentId: string;\n /** Prefix for the wrong-document error, e.g. \"Blob attachment detach\". */\n errorLabel: string;\n execSql?: ExecSql | undefined;\n isRemoteSyncBlocked?: ((organizationId: string) => boolean) | undefined;\n writerProjection?: DocumentWriterProjectionResponse | undefined;\n } & ProjectionVerificationOptions,\n): Promise<{\n manifestIdentity: DocumentManifestIdentity;\n writerProjection: DocumentWriterProjectionResponse;\n} | null> {\n const writerProjection =\n input.writerProjection ??\n (await input.apiClient.getDocumentWriterProjection(input.documentId));\n if (!writerProjection) {\n return null;\n }\n\n await assertDocumentWriterProjectionConsistent(writerProjection, {\n execSql: input.execSql,\n ...projectionVerificationOptions(input),\n });\n const manifestIdentity = readDocumentManifestIdentity(writerProjection);\n if (manifestIdentity.documentId !== input.documentId) {\n throw new Error(\n `${input.errorLabel} writer projection targets wrong document`,\n );\n }\n if (input.isRemoteSyncBlocked?.(manifestIdentity.organizationId)) {\n return null;\n }\n\n return { manifestIdentity, writerProjection };\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"attachmentPersistence.js","sourceRoot":"","sources":["attachmentPersistence.ts"],"names":[],"mappings":"AAcA,MAAM,CAAC,KAAK,UAAU,4BAA4B,CAAC,KAIlD;IACC,KAAK,MAAM,UAAU,IAAI,KAAK,CAAC,WAAW,EAAE,CAAC;QAC3C,MAAM,KAAK,CAAC,WAAW,CAAC,mBAAmB,CAAC,KAAK,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;IACzE,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,6BAA6B,CAAC,KAMnD;IACC,MAAM,KAAK,CAAC,WAAW,CAAC,qBAAqB,CAC3C,KAAK,CAAC,OAAO,EACb,KAAK,CAAC,OAAO,EACb,KAAK,CAAC,MAAM,EACZ,KAAK,CAAC,UAAU,CACjB,CAAC;AACJ,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,mCAAmC,CAAC,KAMzD;IACC,MAAM,KAAK,CAAC,WAAW,CAAC,2BAA2B,CACjD,KAAK,CAAC,OAAO,EACb,KAAK,CAAC,OAAO,EACb,KAAK,CAAC,MAAM,EACZ,KAAK,CAAC,UAAU,CACjB,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,6BAA6B,CAAC,KAInD;IACC,MAAM,KAAK,CAAC,WAAW,CAAC,qBAAqB,CAC3C,KAAK,CAAC,OAAO,EACb,KAAK,CAAC,UAAU,CACjB,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,+BAA+B,CAAC,KAMrD;IACC,MAAM,KAAK,CAAC,WAAW,CAAC,uBAAuB,CAC7C,KAAK,CAAC,OAAO,EACb,KAAK,CAAC,OAAO,EACb,KAAK,CAAC,MAAM,EACZ,KAAK,CAAC,UAAU,CACjB,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,8BAA8B,CAAC,KAO9C;IACC,OAAO,KAAK,CAAC,WAAW,CAAC,sBAAsB,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;AACxE,CAAC","sourcesContent":["/**\n * Attachment-slot persistence for stored documents.\n *\n * These are the workflow-level seams the document store writes attachment rows\n * through: the pending-upload queue, the local blob projection, and the detach\n * marker that keeps an unlinked slot's row alive for the next sync.\n */\nimport type {\n DocumentsPersistence,\n LocalAttachmentRecord,\n PendingAttachmentRecord,\n} from \"../../data/persistence/documents/documentsPersistence\";\nimport type { ExecSql } from \"../../data/sqlite/sqlSchema\";\n\nexport async function saveLocalDocumentAttachments(input: {\n attachments: ReadonlyArray<LocalAttachmentRecord>;\n execSql: ExecSql;\n persistence: DocumentsPersistence;\n}): Promise<void> {\n for (const attachment of input.attachments) {\n await input.persistence.saveLocalAttachment(input.execSql, attachment);\n }\n}\n\nexport async function deleteLocalDocumentAttachment(input: {\n execSql: ExecSql;\n localId: string;\n persistence: DocumentsPersistence;\n slotId: string;\n storageKey: string;\n}): Promise<void> {\n await input.persistence.deleteLocalAttachment(\n input.execSql,\n input.localId,\n input.slotId,\n input.storageKey,\n );\n}\n\n/**\n * Mark a slot's local blob row detached without dropping it.\n *\n * Unlinking an attachment from a synced document cannot delete the row: it is\n * also the marker `syncDetachedAttachments` needs to detach the remote binding\n * on the next sync (and to survive a restart before that sync runs). Marking it\n * keeps that marker while taking the slot out of the local blob read models\n * right away, so the blob browser stops listing a reference the document no\n * longer has.\n */\nexport async function markLocalDocumentAttachmentDetached(input: {\n execSql: ExecSql;\n localId: string;\n persistence: DocumentsPersistence;\n slotId: string;\n storageKey: string;\n}): Promise<void> {\n await input.persistence.markLocalAttachmentDetached(\n input.execSql,\n input.localId,\n input.slotId,\n input.storageKey,\n );\n}\n\nexport async function savePendingDocumentAttachment(input: {\n attachment: PendingAttachmentRecord;\n execSql: ExecSql;\n persistence: DocumentsPersistence;\n}): Promise<void> {\n await input.persistence.savePendingAttachment(\n input.execSql,\n input.attachment,\n );\n}\n\nexport async function deletePendingDocumentAttachment(input: {\n execSql: ExecSql;\n localId: string;\n persistence: DocumentsPersistence;\n slotId: string;\n storageKey: string;\n}): Promise<void> {\n await input.persistence.deletePendingAttachment(\n input.execSql,\n input.localId,\n input.slotId,\n input.storageKey,\n );\n}\n\nexport function saveHydratedDocumentAttachment(input: {\n execSql: ExecSql;\n persistence: DocumentsPersistence;\n attachment: LocalAttachmentRecord;\n expectedStorageKey: string | null;\n expectedSnapshotEndVersion: string | null;\n stillCurrent: () => boolean;\n}): Promise<boolean> {\n return input.persistence.saveHydratedAttachment(input.execSql, input);\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"blobMutationLock.js","sourceRoot":"","sources":["blobMutationLock.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,uBAAuB,GACxB,MAAM,6BAA6B,CAAC;AAErC,MAAM,uBAAuB,GAAG,IAAI,OAAO,EAGxC,CAAC;AAEJ;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,iCAAiC,CACrD,OAAgB,EAChB,UAAkB,EAClB,SAA+B;IAE/B,MAAM,gBAAgB,GAAG,uBAAuB,CAAC,OAAO,CAAC,CAAC;IAC1D,MAAM,MAAM,GAAG,uBAAuB,CAAC,GAAG,CAAC,gBAAgB,CAAC,IAAI,IAAI,GAAG,EAAE,CAAC;IAC1E,uBAAuB,CAAC,GAAG,CAAC,gBAAgB,EAAE,MAAM,CAAC,CAAC;IAEtD,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;IAC7D,IAAI,cAAc,GAAe,GAAG,EAAE,CAAC,SAAS,CAAC;IACjD,MAAM,OAAO,GAAG,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;QAC5C,cAAc,GAAG,OAAO,CAAC;IAC3B,CAAC,CAAC,CAAC;IACH,MAAM,eAAe,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;IACxD,MAAM,aAAa,GAAG,eAAe,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,CAAC;IAC1D,MAAM,CAAC,GAAG,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;IACtC,MAAM,eAAe,CAAC;IAEtB,IAAI,CAAC;QACH,OAAO,MAAM,SAAS,EAAE,CAAC;IAC3B,CAAC;YAAS,CAAC;QACT,cAAc,EAAE,CAAC;QACjB,IAAI,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,KAAK,aAAa,EAAE,CAAC;YAC7C,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;YAC1B,IAAI,MAAM,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;gBACtB,uBAAuB,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC;YACnD,CAAC;QACH,CAAC;IACH,CAAC;AACH,CAAC","sourcesContent":["import {\n type ExecSql,\n resolveCanonicalExecSql,\n} from \"../../data/sqlite/sqlSchema\";\n\nconst mutationQueuesByExecSql = new WeakMap<\n ExecSql,\n Map<string, Promise<void>>\n>();\n\n/**\n * Serialize byte-store mutations that address the same document blob key.\n *\n * Lock order is blob key, then the connection-wide SQL mutation lock. Callers\n * must not acquire this lock from inside `runSerializedSqlMutation`.\n */\nexport async function runSerializedDocumentBlobMutation<T>(\n execSql: ExecSql,\n storageKey: string,\n operation: () => Promise<T> | T,\n): Promise<T> {\n const canonicalExecSql = resolveCanonicalExecSql(execSql);\n const queues = mutationQueuesByExecSql.get(canonicalExecSql) ?? new Map();\n mutationQueuesByExecSql.set(canonicalExecSql, queues);\n\n const previous = queues.get(storageKey) ?? Promise.resolve();\n let releaseCurrent: () => void = () => undefined;\n const current = new Promise<void>((resolve) => {\n releaseCurrent = resolve;\n });\n const waitForPrevious = previous.catch(() => undefined);\n const queuedCurrent = waitForPrevious.then(() => current);\n queues.set(storageKey, queuedCurrent);\n await waitForPrevious;\n\n try {\n return await operation();\n } finally {\n releaseCurrent();\n if (queues.get(storageKey) === queuedCurrent) {\n queues.delete(storageKey);\n if (queues.size === 0) {\n mutationQueuesByExecSql.delete(canonicalExecSql);\n }\n }\n }\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"create.js","sourceRoot":"","sources":["create.ts"],"names":[],"mappings":"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","sourcesContent":["import type { DocumentCreateRequest } from \"@tearleads/validators/request\";\nimport {\n type ContainerWriterProjectionResponse,\n DOCUMENT_SYNC_ERROR_CODES,\n type DocumentCreateResponse,\n} from \"@tearleads/validators/response\";\nimport { assertContainerAuthorAccess } from \"../../data/containers/shared/authorAccess\";\nimport { buildDocumentCreatePlan } from \"../../data/documents/shared/events\";\nimport { wrapDocumentContentKeyForCreate } from \"../../data/documents/shared/projection\";\nimport type {\n CreateRemoteDocumentResult,\n DocumentCreateApi,\n DocumentCreateAuthor,\n MaterializedDocumentCreatePlan,\n ProjectionVerificationOptions,\n} from \"../../data/documents/shared/types\";\nimport { projectionVerificationOptions } from \"../../data/documents/shared/types\";\nimport type {\n ProjectionUserKeyResolver,\n ReferencedPrincipalPolicyWarmer,\n} from \"../../data/keyingProjectionVerification\";\nimport {\n collectContainerWriterProjectionPrincipalPolicies,\n nullOnProjectionVerificationCancellation,\n requireProjectionUserKeyResolver,\n} from \"../../data/keyingProjectionVerification\";\nimport { isContainerCreatePending } from \"../../data/persistence/container-contents/pendingContainerCreate\";\nimport type { ExecSql } from \"../../data/sqlite/sqlSchema\";\nimport { recordDocumentAuthorAccessFailure } from \"./authorAccessFailure\";\nimport { adoptExistingRemoteDocument } from \"./createAdoption\";\nimport type { DocumentCreateTerminalFailureHandler } from \"./createProjectionFetch\";\nimport { fetchContainerWriterProjectionForCreate } from \"./createProjectionFetch\";\nimport { acknowledgeRemoteDocumentCreate } from \"./createResponse\";\nimport {\n isDocumentManifestAlreadyExistsConflict,\n shouldRetryWithFreshProjection,\n} from \"./syncFailureClassification\";\n\nexport async function buildMaterializedDocumentCreatePlan(\n input: {\n author: DocumentCreateAuthor;\n containerProjection: ContainerWriterProjectionResponse;\n contentKey?: Uint8Array | undefined;\n contentKeyEpoch?: number | undefined;\n documentId?: string | undefined;\n eventId?: string | undefined;\n execSql?: ExecSql | undefined;\n knownContainerKeks?: ReadonlyMap<string, Uint8Array> | undefined;\n persistVerificationCheckpoints?: boolean | undefined;\n signedAt?: string | undefined;\n targetSecretKey: Uint8Array;\n } & ProjectionVerificationOptions,\n): Promise<MaterializedDocumentCreatePlan> {\n const contentKey =\n input.contentKey ?? crypto.getRandomValues(new Uint8Array(32));\n if (contentKey.byteLength !== 32) {\n throw new Error(\"Document content key must be 32 bytes\");\n }\n // Resolved before wrapping: each envelope is sealed to its document and\n // content-key epoch.\n const documentId = input.documentId ?? crypto.randomUUID();\n const contentKeyEpoch = input.contentKeyEpoch ?? 1;\n const targetEnvelopes = await wrapDocumentContentKeyForCreate({\n contentKey,\n contentKeyEpoch,\n documentId,\n execSql: input.execSql,\n knownContainerKeks: input.knownContainerKeks,\n persistVerificationCheckpoints: input.persistVerificationCheckpoints,\n projection: input.containerProjection,\n secretKey: input.targetSecretKey,\n ...projectionVerificationOptions(input),\n });\n if (input.resolveProjectionUserKey) {\n const principalPolicies =\n await collectContainerWriterProjectionPrincipalPolicies({\n ...projectionVerificationOptions(input),\n execSql: input.execSql,\n projection: input.containerProjection,\n resolveUserKey: input.resolveProjectionUserKey,\n });\n assertContainerAuthorAccess({\n // Document signing derives its organization from the verified target.\n author: {\n ...input.author,\n organizationId: input.containerProjection.organizationId,\n },\n projection: input.containerProjection,\n principalPolicies,\n minimumAccess: \"write\",\n });\n }\n // The explicit local-trust variant builds provisioning artifacts before\n // their new principal policies exist remotely; remote creates cannot use it.\n const plan = await buildDocumentCreatePlan({\n author: input.author,\n containerProjection: input.containerProjection,\n contentKeyEpoch,\n documentId,\n ...(input.eventId === undefined ? {} : { eventId: input.eventId }),\n ...(input.signedAt === undefined ? {} : { signedAt: input.signedAt }),\n targetEnvelopes,\n });\n\n return {\n contentKey,\n plan,\n };\n}\n\nexport { documentWriterProjectionFromCreateResponse } from \"./createProjection\";\n\ninterface MaterializedDocumentCreatePlanWithProjection {\n readonly containerProjection: ContainerWriterProjectionResponse;\n readonly materializedPlan: MaterializedDocumentCreatePlan;\n}\n\nasync function buildMaterializedDocumentCreatePlanWithFreshProjection(input: {\n apiClient: DocumentCreateApi;\n author: DocumentCreateAuthor;\n containerId: string;\n containerProjection?: ContainerWriterProjectionResponse | undefined;\n contentKey?: Uint8Array | undefined;\n contentKeyEpoch?: number | undefined;\n documentId?: string | undefined;\n eventId?: string | undefined;\n execSql: ExecSql;\n expectedOrganizationId?: string | undefined;\n knownContainerKeks?: ReadonlyMap<string, Uint8Array> | undefined;\n onTerminalSubmitFailure?: DocumentCreateTerminalFailureHandler | undefined;\n persistVerificationCheckpoints?: boolean | undefined;\n resolveProjectionUserKey: ProjectionUserKeyResolver;\n signedAt?: string | undefined;\n stillCurrent?: (() => boolean) | undefined;\n targetSecretKey: Uint8Array;\n warmReferencedPrincipalPolicies?: ReferencedPrincipalPolicyWarmer | undefined;\n}): Promise<MaterializedDocumentCreatePlanWithProjection | null> {\n const buildWithProjection = async (\n containerProjection: ContainerWriterProjectionResponse,\n ) => {\n if (\n containerProjection.containerId !== input.containerId ||\n (input.expectedOrganizationId !== undefined &&\n containerProjection.organizationId !== input.expectedOrganizationId)\n ) {\n throw new Error(\n \"Container writer projection belongs to another container or organization\",\n );\n }\n return {\n containerProjection,\n materializedPlan: await buildMaterializedDocumentCreatePlan({\n author: input.author,\n containerProjection,\n contentKey: input.contentKey,\n contentKeyEpoch: input.contentKeyEpoch,\n documentId: input.documentId,\n eventId: input.eventId,\n execSql: input.execSql,\n knownContainerKeks: input.knownContainerKeks,\n persistVerificationCheckpoints: input.persistVerificationCheckpoints,\n resolveProjectionUserKey: input.resolveProjectionUserKey,\n signedAt: input.signedAt,\n stillCurrent: input.stillCurrent,\n targetSecretKey: input.targetSecretKey,\n warmReferencedPrincipalPolicies: input.warmReferencedPrincipalPolicies,\n }),\n };\n };\n\n const containerProjection =\n input.containerProjection ??\n (await fetchContainerWriterProjectionForCreate({\n apiClient: input.apiClient,\n containerId: input.containerId,\n onTerminalSubmitFailure: input.onTerminalSubmitFailure,\n }));\n if (!containerProjection) {\n return null;\n }\n\n try {\n return await buildWithProjection(containerProjection);\n } catch (error) {\n if (\n !shouldRetryWithFreshProjection(error, (message) =>\n message.includes(\"could not be unwrapped\"),\n )\n ) {\n throw error;\n }\n }\n\n // Only this container's projection was stale; evict just it rather than\n // wiping every cached projection.\n input.apiClient.evictContainerWriterProjection(input.containerId);\n const refreshedProjection = await fetchContainerWriterProjectionForCreate({\n apiClient: input.apiClient,\n containerId: input.containerId,\n onTerminalSubmitFailure: input.onTerminalSubmitFailure,\n });\n return refreshedProjection ? buildWithProjection(refreshedProjection) : null;\n}\n\ninterface RemoteDocumentCreateInput {\n apiClient: DocumentCreateApi;\n author: DocumentCreateAuthor;\n containerId: string;\n containerProjection?: ContainerWriterProjectionResponse | undefined;\n contentKey?: Uint8Array | undefined;\n contentKeyEpoch?: number | undefined;\n documentId?: string | undefined;\n eventId?: string | undefined;\n execSql: ExecSql;\n expectedOrganizationId?: string | undefined;\n isRemoteSyncBlocked?: ((organizationId: string) => boolean) | undefined;\n knownContainerKeks?: ReadonlyMap<string, Uint8Array> | undefined;\n /**\n * Invoked when the create submission fails terminally (not a benign\n * adopt/stale-target conflict) — e.g. the server denies the write. Callers\n * persist the failure so the write queue can surface it.\n */\n onTerminalSubmitFailure?: DocumentCreateTerminalFailureHandler | undefined;\n resolveProjectionUserKey: ProjectionUserKeyResolver;\n signedAt?: string | undefined;\n stillCurrent?: (() => boolean) | undefined;\n targetSecretKey: Uint8Array;\n warmReferencedPrincipalPolicies?: ReferencedPrincipalPolicyWarmer | undefined;\n}\n\nfunction isRemoteDocumentCreatePlanBlocked(\n input: RemoteDocumentCreateInput,\n createPlan: MaterializedDocumentCreatePlanWithProjection,\n): boolean {\n const organizationId = createPlan.containerProjection.organizationId;\n return input.isRemoteSyncBlocked?.(organizationId) ?? false;\n}\n\nasync function submitPlannedDocumentCreate(\n input: RemoteDocumentCreateInput,\n resolveProjectionUserKey: ProjectionUserKeyResolver,\n): Promise<{\n readonly createPlan: MaterializedDocumentCreatePlanWithProjection;\n readonly submission: DocumentCreateSubmission;\n} | null> {\n const verificationOptions = { stillCurrent: input.stillCurrent };\n const warmReferencedPrincipalPolicies = input.warmReferencedPrincipalPolicies;\n let createPlan = await buildMaterializedDocumentCreatePlanWithFreshProjection(\n {\n apiClient: input.apiClient,\n author: input.author,\n containerId: input.containerId,\n containerProjection: input.containerProjection,\n contentKey: input.contentKey,\n contentKeyEpoch: input.contentKeyEpoch,\n documentId: input.documentId,\n eventId: input.eventId,\n execSql: input.execSql,\n expectedOrganizationId: input.expectedOrganizationId,\n knownContainerKeks: input.knownContainerKeks,\n onTerminalSubmitFailure: input.onTerminalSubmitFailure,\n resolveProjectionUserKey,\n signedAt: input.signedAt,\n targetSecretKey: input.targetSecretKey,\n warmReferencedPrincipalPolicies,\n ...verificationOptions,\n },\n );\n if (!createPlan) {\n return null;\n }\n if (isRemoteDocumentCreatePlanBlocked(input, createPlan)) return null;\n if (input.stillCurrent?.() === false) return null;\n let submission = await submitDocumentCreate(\n input.apiClient,\n createPlan.materializedPlan.plan.request,\n createPlan.containerProjection.organizationId,\n );\n if (isStaleDocumentCreateTargetConflict(submission)) {\n if (input.stillCurrent?.() === false) {\n return { createPlan, submission };\n }\n input.apiClient.evictContainerWriterProjection(input.containerId);\n const firstPlan = createPlan.materializedPlan;\n const refreshedPlan =\n await buildMaterializedDocumentCreatePlanWithFreshProjection({\n apiClient: input.apiClient,\n author: input.author,\n containerId: input.containerId,\n contentKey: firstPlan.contentKey,\n contentKeyEpoch:\n firstPlan.plan.request.contentKeyBundle.contentKeyEpoch,\n documentId: firstPlan.plan.documentId,\n eventId: firstPlan.plan.event.eventId,\n execSql: input.execSql,\n expectedOrganizationId: input.expectedOrganizationId,\n knownContainerKeks: input.knownContainerKeks,\n onTerminalSubmitFailure: input.onTerminalSubmitFailure,\n resolveProjectionUserKey,\n signedAt: firstPlan.plan.event.signedAt,\n targetSecretKey: input.targetSecretKey,\n warmReferencedPrincipalPolicies,\n ...verificationOptions,\n });\n if (!refreshedPlan) {\n return null;\n }\n if (isRemoteDocumentCreatePlanBlocked(input, refreshedPlan)) return null;\n createPlan = refreshedPlan;\n if (input.stillCurrent?.() === false) return null;\n submission = await submitDocumentCreate(\n input.apiClient,\n createPlan.materializedPlan.plan.request,\n createPlan.containerProjection.organizationId,\n );\n }\n return { createPlan, submission };\n}\n\nexport async function createRemoteDocument(\n input: RemoteDocumentCreateInput,\n): Promise<CreateRemoteDocumentResult | null> {\n // The store retries once the folder's own create settles.\n if (await isContainerCreatePending(input.execSql, input.containerId)) {\n return null;\n }\n const resolveProjectionUserKey = requireProjectionUserKeyResolver(\n input.resolveProjectionUserKey,\n \"Remote document create\",\n );\n const plannedSubmission = await recordDocumentAuthorAccessFailure(\n () =>\n nullOnProjectionVerificationCancellation(() =>\n submitPlannedDocumentCreate(input, resolveProjectionUserKey),\n ),\n input.onTerminalSubmitFailure,\n );\n if (!plannedSubmission) {\n return null;\n }\n const { createPlan, submission } = plannedSubmission;\n if (input.stillCurrent?.() === false) return null;\n if (submission.ok)\n return acknowledgeRemoteDocumentCreate({\n ...input,\n ...createPlan,\n resolveProjectionUserKey,\n response: submission.data,\n });\n\n // A stable documentId means a retry after a lost create response re-submits\n // the same id; the server then reports the manifest already exists. That is\n // not a failure — the first attempt committed. Adopt the existing remote\n // document instead of leaking a duplicate. Requires the stable id we sent, so\n // we can fetch its projection back.\n const stableDocumentId = input.documentId;\n if (stableDocumentId && isDocumentManifestAlreadyExistsConflict(submission)) {\n if (input.stillCurrent?.() === false) return null;\n const adopted = await nullOnProjectionVerificationCancellation(() =>\n adoptExistingRemoteDocument({\n apiClient: input.apiClient,\n documentId: stableDocumentId,\n execSql: input.execSql,\n expectedContainerId: input.containerId,\n expectedOrganizationId:\n input.expectedOrganizationId ??\n createPlan.containerProjection.organizationId,\n expectedSignerUserId: input.author.signerUserId,\n resolveProjectionUserKey,\n stillCurrent: input.stillCurrent,\n targetSecretKey: input.targetSecretKey,\n warmReferencedPrincipalPolicies: input.warmReferencedPrincipalPolicies,\n }),\n );\n if (adopted) {\n return adopted;\n }\n // A conflict is the expected, benign outcome of an idempotent retry after a\n // lost create response. If adoption cannot complete yet (e.g. the writer\n // projection fetch failed transiently), do not surface the conflict as a UI\n // error — the sync engine retries and adopts it on a later tick.\n return null;\n }\n\n submission.report?.();\n await input.onTerminalSubmitFailure?.(submission);\n return null;\n}\n\ntype DocumentCreateSubmission =\n | {\n readonly data: DocumentCreateResponse;\n readonly ok: true;\n }\n | {\n readonly code?: string | undefined;\n readonly message: string;\n readonly ok: false;\n readonly report?: (() => void) | undefined;\n readonly status: number | null;\n };\n\nexport function isStaleDocumentCreateTargetConflict(\n submission: DocumentCreateSubmission,\n): boolean {\n return (\n !submission.ok &&\n submission.status === 409 &&\n submission.code === DOCUMENT_SYNC_ERROR_CODES.stateStale\n );\n}\n\nasync function submitDocumentCreate(\n apiClient: DocumentCreateApi,\n request: DocumentCreateRequest,\n expectedOrganizationId: string,\n): Promise<DocumentCreateSubmission> {\n return apiClient.createDocumentResult(request, {\n expectedPaymentRequiredOrganizationId: expectedOrganizationId,\n reportErrors: false,\n });\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"createAdoption.js","sourceRoot":"","sources":["createAdoption.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n KeyingVerificationError,\n type VerifiedContainerAccessManifest,\n type VerifiedPrincipalPolicy,\n} from \"@tearleads/crypto\";\nimport type { DocumentWriterProjectionResponse } from \"@tearleads/validators/response\";\nimport {\n assertDocumentWriterProjectionConsistent,\n readLinkedContainerIdsFromDocumentManifest,\n unwrapDocumentContentKeyFromWriterProjection,\n} from \"../../data/documents/shared/projection\";\nimport { persistedDocumentCreateStateFromWriterProjection } from \"../../data/documents/shared/responses\";\nimport type {\n CreateRemoteDocumentResult,\n DocumentCreateApi,\n ProjectionVerificationOptions,\n} from \"../../data/documents/shared/types\";\nimport { projectionVerificationOptions } from \"../../data/documents/shared/types\";\nimport {\n readAccessEvent,\n readAccessManifest,\n} from \"../../data/keyingProjectionVerification/readers\";\nimport type { ExecSql } from \"../../data/sqlite/sqlSchema\";\n\ntype RemoteDocumentAdoptionInput = {\n readonly apiClient: DocumentCreateApi;\n readonly documentId: string;\n readonly execSql: ExecSql;\n readonly expectedContainerId: string;\n readonly expectedOrganizationId: string;\n /** The local user whose pending create the retry is recovering. */\n readonly expectedSignerUserId: string;\n readonly targetSecretKey: Uint8Array;\n} & ProjectionVerificationOptions;\n\n/**\n * A retry after a lost create response can only recover the local user's own\n * create: the server serves whatever document holds the stable id we minted,\n * and an honest server only ever committed ours under it. A create event signed\n * by anyone else is a foreign document colliding on that id (a member with\n * write access on the same container, or a dishonest server), which must not be\n * adopted as if it were the pending local write.\n *\n * The create event is located by walking the served head's predecessor chain,\n * not by scanning the history for any parentless manifest: the history is\n * server-supplied, so a dishonest server could splice in a genesis this user\n * signed for a different document. Every manifest on the chain must also name\n * the requested document.\n */\nfunction assertCreateEventSignedLocally(\n input: RemoteDocumentAdoptionInput,\n writerProjection: DocumentWriterProjectionResponse,\n): void {\n const label = \"Document create conflict\";\n const historyByHash = new Map(\n writerProjection.documentManifestHistory.map((bundle) => [\n bundle.manifestHash,\n bundle,\n ]),\n );\n const visited = new Set<string>();\n let bundle = writerProjection.documentManifest;\n for (;;) {\n const manifest = readAccessManifest(bundle.manifest, `${label} manifest`);\n if (\n manifest.objectKind !== \"document\" ||\n manifest.objectId !== input.documentId\n ) {\n throw new KeyingVerificationError(\n \"object_mismatch\",\n `${label} manifest chain names another document`,\n );\n }\n if (manifest.previousManifestHash === null) {\n const createEvent = readAccessEvent(\n bundle.event.event,\n `${label} create event`,\n );\n if (createEvent.signerUserId !== input.expectedSignerUserId) {\n throw new KeyingVerificationError(\n \"signer_mismatch\",\n `${label} create event was signed by another user`,\n );\n }\n return;\n }\n if (visited.has(bundle.manifestHash)) {\n throw new KeyingVerificationError(\n \"invalid_shape\",\n `${label} manifest history is cyclic`,\n );\n }\n visited.add(bundle.manifestHash);\n const previous = historyByHash.get(manifest.previousManifestHash);\n if (!previous) {\n throw new KeyingVerificationError(\n \"invalid_shape\",\n `${label} does not expose its create event`,\n );\n }\n bundle = previous;\n }\n}\n\nfunction assertExpectedAdoptionScope(\n input: RemoteDocumentAdoptionInput,\n writerProjection: DocumentWriterProjectionResponse,\n): void {\n const linkedContainerIds =\n readLinkedContainerIdsFromDocumentManifest(writerProjection);\n const expectedPath = writerProjection.authorizingContainerPaths.find(\n (projection) =>\n projection.containerId === input.expectedContainerId &&\n projection.organizationId === input.expectedOrganizationId,\n );\n if (\n linkedContainerIds.length !== 1 ||\n linkedContainerIds[0] !== input.expectedContainerId ||\n !expectedPath\n ) {\n throw new Error(\n \"Document create conflict belongs to another container or organization\",\n );\n }\n}\n\n/** Recover a committed retry only when it belongs to the intended org scope. */\nexport async function adoptExistingRemoteDocument(\n input: RemoteDocumentAdoptionInput,\n): Promise<CreateRemoteDocumentResult | null> {\n const writerProjection = await input.apiClient.getDocumentWriterProjection(\n input.documentId,\n );\n if (!writerProjection) return null;\n\n // Reject a foreign collision before verification can pin its checkpoints.\n assertExpectedAdoptionScope(input, writerProjection);\n assertCreateEventSignedLocally(input, writerProjection);\n const verifiedByHash = new Map<string, VerifiedContainerAccessManifest>();\n const principalPolicyCache = new Map<string, VerifiedPrincipalPolicy>();\n const targets = await assertDocumentWriterProjectionConsistent(\n writerProjection,\n {\n execSql: input.execSql,\n principalPolicyCache,\n verifiedByHash,\n ...projectionVerificationOptions(input),\n },\n );\n if (\n targets.length !== 1 ||\n targets[0]?.containerId !== input.expectedContainerId\n ) {\n throw new Error(\n \"Document create conflict belongs to another container or organization\",\n );\n }\n const contentKey = await unwrapDocumentContentKeyFromWriterProjection({\n execSql: input.execSql,\n principalPolicyCache,\n secretKey: input.targetSecretKey,\n verifiedByHash,\n writerProjection,\n ...projectionVerificationOptions(input),\n });\n if (input.stillCurrent?.() === false) return null;\n input.apiClient.primeDocumentWriterProjection(\n writerProjection.documentId,\n writerProjection,\n );\n return {\n contentKey,\n documentId: writerProjection.documentId,\n persistedState:\n persistedDocumentCreateStateFromWriterProjection(writerProjection),\n writerProjection,\n };\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"createProjectionFetch.js","sourceRoot":"","sources":["createProjectionFetch.ts"],"names":[],"mappings":"AAQA;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,KAAK,UAAU,uCAAuC,CAAC,KAI7D;IACC,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,SAAS,CAAC,kCAAkC,CACrE,KAAK,CAAC,WAAW,EACjB,EAAE,YAAY,EAAE,KAAK,EAAE,CACxB,CAAC;IACF,IAAI,MAAM,CAAC,EAAE,EAAE,CAAC;QACd,OAAO,MAAM,CAAC,IAAI,CAAC;IACrB,CAAC;IACD,MAAM,CAAC,MAAM,EAAE,CAAC;IAChB,MAAM,KAAK,CAAC,uBAAuB,EAAE,CAAC,MAAM,CAAC,CAAC;IAC9C,OAAO,IAAI,CAAC;AACd,CAAC","sourcesContent":["import type { ContainerWriterProjectionResponse } from \"@tearleads/validators/response\";\nimport type { DocumentCreateApi } from \"../../data/documents/shared/types\";\n\nexport type DocumentCreateTerminalFailureHandler = (failure: {\n readonly message: string;\n readonly status: number | null;\n}) => Promise<void> | void;\n\n/**\n * Resolve the container writer projection a create is authored against,\n * persisting a terminal fetch failure through the caller's handler. A pending\n * local create can never submit without this projection, so the failure (e.g.\n * a 402 billing block or a 403 after access revocation) is what the write\n * queue must surface — collapsing it to a silent null left the queued create\n * invisible forever: no failure row, no attempt timestamp, and sync telemetry\n * reporting no pending work.\n *\n * The recorded row follows the standard failure lifecycle rather than\n * sticking: a document whose create later succeeds cannot skip its follow-up\n * sync (its record carries no commit LSN until a sync response persists one,\n * so shouldSkipCleanScheduledDocumentSync stays false), and that clean pass\n * clears the row. Across restarts the row itself is a priming ticket that\n * re-drives the store, exactly like a recorded revalidation refusal.\n */\nexport async function fetchContainerWriterProjectionForCreate(input: {\n apiClient: DocumentCreateApi;\n containerId: string;\n onTerminalSubmitFailure?: DocumentCreateTerminalFailureHandler | undefined;\n}): Promise<ContainerWriterProjectionResponse | null> {\n const result = await input.apiClient.getContainerWriterProjectionResult(\n input.containerId,\n { reportErrors: false },\n );\n if (result.ok) {\n return result.data;\n }\n result.report();\n await input.onTerminalSubmitFailure?.(result);\n return null;\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"createResponse.js","sourceRoot":"","sources":["createResponse.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,2BAA2B,EAAE,MAAM,qDAAqD,CAAC;AAClG,OAAO,EAAE,wCAAwC,EAAE,MAAM,wCAAwC,CAAC;AAClG,OAAO,EAAE,wCAAwC,EAAE,MAAM,uCAAuC,CAAC;AASjG,OAAO,EAAE,oCAAoC,EAAE,MAAM,+DAA+D,CAAC;AACrH,OAAO,EAAE,wCAAwC,EAAE,MAAM,+CAA+C,CAAC;AAEzG,OAAO,EAAE,2BAA2B,EAAE,MAAM,kBAAkB,CAAC;AAC/D,OAAO,EAAE,0CAA0C,EAAE,MAAM,oBAAoB,CAAC;AAEhF,mFAAmF;AACnF,MAAM,CAAC,KAAK,UAAU,+BAA+B,CACnD,KASiC;IAEjC,MAAM,EAAE,gBAAgB,EAAE,QAAQ,EAAE,GAAG,KAAK,CAAC;IAC7C,MAAM,cAAc,GAAG,wCAAwC,CAC7D,gBAAgB,CAAC,IAAI,EACrB,QAAQ,CACT,CAAC;IACF,MAAM,2BAA2B,CAAC;QAChC,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,IAAI,EAAE,gBAAgB,CAAC,IAAI;QAC3B,YAAY,EAAE,KAAK,CAAC,YAAY;KACjC,CAAC,CAAC;IACH,IAAI,KAAK,CAAC,YAAY,EAAE,EAAE,KAAK,KAAK;QAAE,OAAO,IAAI,CAAC;IAClD,MAAM,gBAAgB,GAAG,0CAA0C,CAAC,KAAK,CAAC,CAAC;IAC3E,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,wCAAwC,CAAC,GAAG,EAAE,CAClE,wCAAwC,CAAC,gBAAgB,EAAE,KAAK,CAAC,CAClE,CAAC;QACF,IAAI,CAAC,OAAO,IAAI,KAAK,CAAC,YAAY,EAAE,EAAE,KAAK,KAAK;YAAE,OAAO,IAAI,CAAC;IAChE,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,CAAC,CAAC,KAAK,YAAY,oCAAoC,CAAC;YAAE,MAAM,KAAK,CAAC;QAC1E,2EAA2E;QAC3E,6EAA6E;QAC7E,6EAA6E;QAC7E,OAAO,wCAAwC,CAAC,GAAG,EAAE,CACnD,2BAA2B,CAAC;YAC1B,GAAG,KAAK;YACR,UAAU,EAAE,QAAQ,CAAC,EAAE;YACvB,mBAAmB,EAAE,KAAK,CAAC,mBAAmB,CAAC,WAAW;YAC1D,sBAAsB,EAAE,KAAK,CAAC,mBAAmB,CAAC,cAAc;YAChE,oBAAoB,EAAE,KAAK,CAAC,MAAM,CAAC,YAAY;SAChD,CAAC,CACH,CAAC;IACJ,CAAC;IACD,KAAK,CAAC,SAAS,CAAC,6BAA6B,CAAC,QAAQ,CAAC,EAAE,EAAE,gBAAgB,CAAC,CAAC;IAC7E,OAAO;QACL,UAAU,EAAE,gBAAgB,CAAC,UAAU;QACvC,UAAU,EAAE,QAAQ,CAAC,EAAE;QACvB,cAAc;QACd,IAAI,EAAE,gBAAgB,CAAC,IAAI;QAC3B,QAAQ;QACR,gBAAgB;KACjB,CAAC;AACJ,CAAC","sourcesContent":["import type {\n ContainerWriterProjectionResponse,\n DocumentCreateResponse,\n} from \"@tearleads/validators/response\";\nimport { acknowledgeDocumentMutation } from \"../../data/documents/shared/mutationAcknowledgement\";\nimport { assertDocumentWriterProjectionConsistent } from \"../../data/documents/shared/projection\";\nimport { persistedDocumentCreateStateFromResponse } from \"../../data/documents/shared/responses\";\nimport type {\n CreateRemoteDocumentResult,\n DocumentCreateApi,\n DocumentCreateAuthor,\n MaterializedDocumentCreatePlan,\n ProjectionVerificationOptions,\n} from \"../../data/documents/shared/types\";\nimport type { ProjectionUserKeyResolver } from \"../../data/keyingProjectionVerification\";\nimport { ProjectionDependencyUnavailableError } from \"../../data/keyingProjectionVerification/dependencyUnavailable\";\nimport { nullOnProjectionVerificationCancellation } from \"../../data/keyingProjectionVerification/types\";\nimport type { ExecSql } from \"../../data/sqlite/sqlSchema\";\nimport { adoptExistingRemoteDocument } from \"./createAdoption\";\nimport { documentWriterProjectionFromCreateResponse } from \"./createProjection\";\n\n/** A matched acknowledgement remains committed if authorization evidence races. */\nexport async function acknowledgeRemoteDocumentCreate(\n input: {\n readonly apiClient: DocumentCreateApi;\n readonly author: DocumentCreateAuthor;\n readonly containerProjection: ContainerWriterProjectionResponse;\n readonly execSql: ExecSql;\n readonly materializedPlan: MaterializedDocumentCreatePlan;\n readonly resolveProjectionUserKey: ProjectionUserKeyResolver;\n readonly response: DocumentCreateResponse;\n readonly targetSecretKey: Uint8Array;\n } & ProjectionVerificationOptions,\n): Promise<CreateRemoteDocumentResult | null> {\n const { materializedPlan, response } = input;\n const persistedState = persistedDocumentCreateStateFromResponse(\n materializedPlan.plan,\n response,\n );\n await acknowledgeDocumentMutation({\n execSql: input.execSql,\n plan: materializedPlan.plan,\n stillCurrent: input.stillCurrent,\n });\n if (input.stillCurrent?.() === false) return null;\n const writerProjection = documentWriterProjectionFromCreateResponse(input);\n try {\n const targets = await nullOnProjectionVerificationCancellation(() =>\n assertDocumentWriterProjectionConsistent(writerProjection, input),\n );\n if (!targets || input.stillCurrent?.() === false) return null;\n } catch (error) {\n if (!(error instanceof ProjectionDependencyUnavailableError)) throw error;\n // A principal pin can advance while POST is in flight. Recover the already\n // committed document from fresh evidence, without submitting another create.\n // The adoption path still verifies its author, scope, chain and key binding.\n return nullOnProjectionVerificationCancellation(() =>\n adoptExistingRemoteDocument({\n ...input,\n documentId: response.id,\n expectedContainerId: input.containerProjection.containerId,\n expectedOrganizationId: input.containerProjection.organizationId,\n expectedSignerUserId: input.author.signerUserId,\n }),\n );\n }\n input.apiClient.primeDocumentWriterProjection(response.id, writerProjection);\n return {\n contentKey: materializedPlan.contentKey,\n documentId: response.id,\n persistedState,\n plan: materializedPlan.plan,\n response,\n writerProjection,\n };\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"documentCreationPersistence.js","sourceRoot":"","sources":["documentCreationPersistence.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EACL,mBAAmB,EACnB,yBAAyB,GAC1B,MAAM,iBAAiB,CAAC;AAQzB,MAAM,UAAU,yBAAyB,CAAC,KAUzC;IACC,OAAO,KAAK,CAAC,WAAW,CAAC,mCAAmC,CAC1D,KAAK,CAAC,OAAO,EACb,KAAK,CAAC,MAAM,EACZ;QACE,gBAAgB,EAAE,mBAAmB,CAAC,KAAK,CAAC,UAAU,CAAC;QACvD,QAAQ,EAAE,aAAa,CAAC,yBAAyB,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;KACrE,EACD,KAAK,CAAC,aAAa,IAAI,KAAK,CAAC,YAAY;QACvC,CAAC,CAAC;YACE,GAAG,CAAC,KAAK,CAAC,aAAa;gBACrB,CAAC,CAAC,EAAE,aAAa,EAAE,KAAK,CAAC,aAAa,EAAE;gBACxC,CAAC,CAAC,EAAE,CAAC;YACP,GAAG,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,KAAK,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACpE;QACH,CAAC,CAAC,SAAS,EACb,KAAK,CAAC,oBAAoB,CAC3B,CAAC;AACJ,CAAC","sourcesContent":["import { bytesToBase64 } from \"@tearleads/encoding\";\nimport {\n encodeVersionVector,\n exportFullHistorySnapshot,\n} from \"@tearleads/loro\";\nimport type {\n DocumentsPersistence,\n StoredDocumentRecord,\n} from \"../../data/persistence/documents/documentsPersistence\";\nimport type { PendingUpdateFields } from \"../../data/sqlite/documentPersistence\";\nimport type { ExecSql } from \"../../data/sqlite/sqlSchema\";\n\nexport function createInitialDocumentRows(input: {\n currentDoc: Parameters<typeof encodeVersionVector>[0];\n execSql: ExecSql;\n persistence: DocumentsPersistence;\n pendingUpdate?: PendingUpdateFields | undefined;\n record: StoredDocumentRecord;\n stillCurrent?: (() => boolean) | undefined;\n saveClientProjection: Parameters<\n DocumentsPersistence[\"createDocumentWithHistoryCheckpoint\"]\n >[4];\n}): Promise<string | null> {\n return input.persistence.createDocumentWithHistoryCheckpoint(\n input.execSql,\n input.record,\n {\n endVersionVector: encodeVersionVector(input.currentDoc),\n snapshot: bytesToBase64(exportFullHistorySnapshot(input.currentDoc)),\n },\n input.pendingUpdate || input.stillCurrent\n ? {\n ...(input.pendingUpdate\n ? { pendingUpdate: input.pendingUpdate }\n : {}),\n ...(input.stillCurrent ? { stillCurrent: input.stillCurrent } : {}),\n }\n : undefined,\n input.saveClientProjection,\n );\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"initialSync.js","sourceRoot":"","sources":["initialSync.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,yBAAyB,EAAE,MAAM,mCAAmC,CAAC;AAC9E,OAAO,EAAE,wBAAwB,EAAE,MAAM,+CAA+C,CAAC;AACzF,OAAO,EAAE,4BAA4B,EAAE,MAAM,oCAAoC,CAAC;AAClF,OAAO,EAAE,iBAAiB,EAAE,MAAM,wCAAwC,CAAC;AAM3E,OAAO,EAAE,0BAA0B,EAAE,MAAM,oBAAoB,CAAC;AAEhE;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,+BAA+B,CAAC,KAKrD;IACC,MAAM,aAAa,GAAG,yBAAyB,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;IACrE,IAAI,CAAC,aAAa,EAAE,CAAC;QACnB,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;IAC3D,CAAC;IAED,MAAM,UAAU,GAAG,KAAK,CAAC,oBAAoB,CAAC,IAAI,CAAC,UAAU,CAAC;IAC9D,MAAM,gBAAgB,GACpB,KAAK,CAAC,oBAAoB,CAAC,IAAI,CAAC,OAAO,CAAC,gBAAgB,CAAC;IAC3D,MAAM,aAAa,GAAwB;QACzC,EAAE,EAAE,MAAM,CAAC,UAAU,EAAE;QACvB,GAAG,aAAa;KACjB,CAAC;IACF,MAAM,SAAS,GAAG,MAAM,4BAA4B,CAAC;QACnD,kBAAkB,EAAE,MAAM,wBAAwB,CAChD,KAAK,CAAC,oBAAoB,CAAC,UAAU,CACtC;QACD,eAAe,EAAE,gBAAgB,CAAC,eAAe;QACjD,UAAU;QACV,cAAc,EAAE,KAAK,CAAC,mBAAmB,CAAC,cAAc;QACxD,MAAM,EAAE,aAAa;KACtB,CAAC,CAAC;IACH,MAAM,cAAc,GAAG,MAAM,0BAA0B,CAAC;QACtD,4BAA4B,EAAE;YAC5B,iBAAiB,CAAC,KAAK,CAAC,mBAAmB,CAAC,IAAI,CAAC;SAClD;QACD,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,eAAe,EAAE,gBAAgB,CAAC,eAAe;QACjD,UAAU;QACV,2BAA2B,EAAE,gBAAgB,CAAC,mBAAmB;QACjE,kBAAkB,EAAE,gBAAgB,CAAC,UAAU;QAC/C,cAAc,EAAE,KAAK,CAAC,mBAAmB,CAAC,cAAc;QACxD,QAAQ,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QAClC,MAAM,EAAE;YACN,eAAe,EAAE,SAAS,CAAC,eAAe;YAC1C,aAAa,EAAE,SAAS,CAAC,aAAa;YACtC,EAAE,EAAE,aAAa,CAAC,EAAE;YACpB,uBAAuB,EAAE,aAAa,CAAC,uBAAuB;YAC9D,yBAAyB,EAAE,aAAa,CAAC,yBAAyB;YAClE,YAAY,EAAE,SAAS,CAAC,YAAY;YACpC,cAAc,EAAE,SAAS,CAAC,cAAc;YACxC,aAAa,EAAE,SAAS,CAAC,aAAa;SACvC;KACF,CAAC,CAAC;IAEH,OAAO;QACL,4BAA4B,EAAE;YAC5B,iBAAiB,CAAC,KAAK,CAAC,mBAAmB,CAAC,IAAI,CAAC;SAClD;QACD,gBAAgB;QAChB,eAAe,EAAE,gBAAgB,CAAC,eAAe;QACjD,2BAA2B,EAAE,gBAAgB,CAAC,mBAAmB;QACjE,kBAAkB,EAAE,gBAAgB,CAAC,UAAU;QAC/C,yEAAyE;QACzE,wEAAwE;QACxE,kBAAkB,EAAE,aAAa,CAAC,uBAAuB;QACzD,eAAe,EAAE,CAAC,cAAc,CAAC;QACjC,sBAAsB,EAAE,IAAI;KAC7B,CAAC;AACJ,CAAC","sourcesContent":["import type { DocumentSyncRequest } from \"@tearleads/validators/request\";\nimport type { ContainerWriterProjectionResponse } from \"@tearleads/validators/response\";\nimport { createPendingUpdateFields } from \"../../data/documents/documentSync\";\nimport { importContentKeyMaterial } from \"../../data/documents/shared/contentRecordKeys\";\nimport { encryptDocumentPendingUpdate } from \"../../data/documents/shared/crypto\";\nimport { containerPathRefs } from \"../../data/documents/shared/projection\";\nimport type {\n DocumentCreateAuthor,\n MaterializedDocumentCreatePlan,\n} from \"../../data/documents/shared/types\";\nimport type { PendingUpdateRecord } from \"../../data/sqlite/documentPersistence\";\nimport { signDocumentOutgoingUpdate } from \"./syncPlanIdentity\";\n\n/**\n * Builds the single encrypted initial write for a provisioned document. The\n * server commits it with the organization and document manifest transaction.\n */\nexport async function buildInitialDocumentSyncRequest(input: {\n readonly author: DocumentCreateAuthor;\n readonly containerProjection: ContainerWriterProjectionResponse;\n readonly initialUpdate: Uint8Array;\n readonly materializedDocument: MaterializedDocumentCreatePlan;\n}): Promise<DocumentSyncRequest> {\n const pendingFields = createPendingUpdateFields(input.initialUpdate);\n if (!pendingFields) {\n throw new Error(\"Initial document sync update is empty\");\n }\n\n const documentId = input.materializedDocument.plan.documentId;\n const contentKeyBundle =\n input.materializedDocument.plan.request.contentKeyBundle;\n const pendingUpdate: PendingUpdateRecord = {\n id: crypto.randomUUID(),\n ...pendingFields,\n };\n const encrypted = await encryptDocumentPendingUpdate({\n contentKeyMaterial: await importContentKeyMaterial(\n input.materializedDocument.contentKey,\n ),\n contentKeyEpoch: contentKeyBundle.contentKeyEpoch,\n documentId,\n organizationId: input.containerProjection.organizationId,\n update: pendingUpdate,\n });\n const outgoingUpdate = await signDocumentOutgoingUpdate({\n authorizingContainerPathRefs: [\n containerPathRefs(input.containerProjection.path),\n ],\n author: input.author,\n contentKeyEpoch: contentKeyBundle.contentKeyEpoch,\n documentId,\n expectedLinkSetManifestHash: contentKeyBundle.linkSetManifestHash,\n expectedTargetHash: contentKeyBundle.targetHash,\n organizationId: input.containerProjection.organizationId,\n signedAt: new Date().toISOString(),\n update: {\n contentRecordId: encrypted.contentRecordId,\n encryptedData: encrypted.encryptedData,\n id: pendingUpdate.id,\n partialEndVersionVector: pendingUpdate.partialEndVersionVector,\n partialStartVersionVector: pendingUpdate.partialStartVersionVector,\n metadataHash: encrypted.metadataHash,\n ciphertextHash: encrypted.ciphertextHash,\n plaintextHash: encrypted.plaintextHash,\n },\n });\n\n return {\n authorizingContainerPathRefs: [\n containerPathRefs(input.containerProjection.path),\n ],\n contentKeyBundle,\n contentKeyEpoch: contentKeyBundle.contentKeyEpoch,\n expectedLinkSetManifestHash: contentKeyBundle.linkSetManifestHash,\n expectedTargetHash: contentKeyBundle.targetHash,\n // The provisioning device already holds this exact initialized snapshot,\n // so it does not need the transaction response to echo the update back.\n localVersionVector: pendingUpdate.partialEndVersionVector,\n outgoingUpdates: [outgoingUpdate],\n supportsPullPagination: true,\n };\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"linkSet.js","sourceRoot":"","sources":["linkSet.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n computeAccessManifestHash,\n computeDocumentContentKeyTargetHash,\n DOCUMENT_CONTENT_KEY_WRAP_SUITE,\n type DocumentContentKeyTarget,\n type DocumentLinkSetManifestState,\n deriveDocumentLinkSetManifest,\n wrapContentKey,\n} from \"@tearleads/crypto\";\nimport { bytesToBase64 } from \"@tearleads/encoding\";\nimport { isPlainObject as isPlainRecord } from \"@tearleads/validators/isPlainObject\";\nimport type { DocumentContentKeyTargetEnvelope } from \"@tearleads/validators/request\";\nimport type {\n ContainerWriterProjectionResponse,\n DocumentWriterProjectionResponse,\n} from \"@tearleads/validators/response\";\nimport {\n MAX_DOCUMENT_SYNC_AUTHORIZATION_PATH_REFS,\n MAX_DOCUMENT_SYNC_CONTENT_KEY_TARGETS,\n} from \"@tearleads/validators/util\";\nimport {\n assertContainerKekPathCurrent,\n assertDocumentKekPathsCurrent,\n} from \"../../data/documents/shared/containerKekCurrency\";\nimport { buildDocumentLinkSetEventPlan } from \"../../data/documents/shared/events\";\nimport {\n assertDocumentWriterProjectionConsistent,\n collectContainerKeksForDocumentSync,\n containerPathRefs,\n currentDocumentTargets,\n deriveDocumentTargetFromProjection,\n mergeTargetEnvelopes,\n readLinkedContainerIdsFromDocumentManifest,\n unwrapContainerKekPath,\n unwrapDocumentContentKeyFromWriterProjection,\n verifiedDocumentWrapTargets,\n} from \"../../data/documents/shared/projection\";\nimport {\n assertDocumentManifestBundleConsistent,\n describeDocumentTargetKek,\n sortDocumentTargets,\n targetKey,\n uniqueSortedStrings,\n} from \"../../data/documents/shared/readers\";\nimport {\n type BuildDocumentLinkSetMutationPlanInput,\n type DocumentCreateAuthor,\n type DocumentLinkSetMutationOperation,\n type DocumentLinkSetMutationPlan,\n type DocumentLinkSetTargetState,\n type MaterializedDocumentLinkSetMutationPlan,\n type ProjectionVerificationOptions,\n projectionVerificationOptions,\n} from \"../../data/documents/shared/types\";\nimport { readCanonicalRecord } from \"../../data/keying/canonicalJson\";\nimport type { PrincipalPolicyCache } from \"../../data/keyingProjectionVerification\";\nimport type { ExecSql } from \"../../data/sqlite/sqlSchema\";\nimport {\n assertDocumentLinkAuthorAccess,\n verifyDocumentLinkSetCurrentPolicies,\n} from \"./linkSetAuthority\";\n\nimport {\n assertSubtreePurgePath,\n type SubtreePurgeRoot,\n} from \"./subtreePurgeScope\";\n\nfunction deriveDocumentLinkSetTargetState(input: {\n operation: DocumentLinkSetMutationOperation;\n targetContainerProjection: ContainerWriterProjectionResponse;\n writerProjection: DocumentWriterProjectionResponse;\n}): DocumentLinkSetTargetState {\n const currentTargets = currentDocumentTargets(input.writerProjection);\n const currentLinkedContainerIds = readLinkedContainerIdsFromDocumentManifest(\n input.writerProjection,\n );\n const target = deriveDocumentTargetFromProjection(\n input.targetContainerProjection,\n );\n const currentTarget = currentTargets.find(\n (candidate) => candidate.containerId === target.containerId,\n );\n\n if (input.operation === \"link\") {\n if (currentTarget) {\n throw new Error(\"Document link target is already linked\");\n }\n assertDocumentLinkTargetCapacity(currentTargets.length);\n assertDocumentLinkAuthorizationPathCapacity(\n input.writerProjection.authorizingContainerPaths.map(\n (projection) => projection.path.length,\n ),\n input.targetContainerProjection.path.length,\n );\n\n return {\n currentTargets,\n linkedContainerIds: uniqueSortedStrings([\n ...currentLinkedContainerIds,\n target.containerId,\n ]),\n target,\n targets: sortDocumentTargets([...currentTargets, target]),\n };\n }\n\n if (!currentTarget) {\n throw new Error(\"Document unlink target is not linked\");\n }\n if (targetKey(currentTarget) !== targetKey(target)) {\n throw new Error(\"Document unlink target projection is stale\");\n }\n\n const linkedContainerIds = currentLinkedContainerIds.filter(\n (containerId) => containerId !== target.containerId,\n );\n if (linkedContainerIds.length === 0) {\n throw new Error(\"Document unlink must leave a linked container\");\n }\n\n return {\n currentTargets,\n linkedContainerIds,\n target,\n targets: currentTargets.filter(\n (candidate) => candidate.containerId !== target.containerId,\n ),\n };\n}\n\nexport function assertDocumentLinkTargetCapacity(\n currentTargetCount: number,\n): void {\n if (currentTargetCount >= MAX_DOCUMENT_SYNC_CONTENT_KEY_TARGETS) {\n throw new RangeError(\n `A document cannot be linked to more than ${MAX_DOCUMENT_SYNC_CONTENT_KEY_TARGETS} containers`,\n );\n }\n}\n\nexport function assertDocumentLinkAuthorizationPathCapacity(\n currentPathLengths: readonly number[],\n targetPathLength: number,\n): void {\n const totalReferences = currentPathLengths.reduce(\n (total, length) => total + length,\n targetPathLength,\n );\n if (totalReferences > MAX_DOCUMENT_SYNC_AUTHORIZATION_PATH_REFS) {\n throw new RangeError(\n `Document links cannot require more than ${MAX_DOCUMENT_SYNC_AUTHORIZATION_PATH_REFS} authorization references`,\n );\n }\n}\n\nasync function wrapDocumentContentKeyForTargets(input: {\n contentKey: Uint8Array;\n contentKeyEpoch: number;\n documentId: string;\n keksByEpochId: ReadonlyMap<string, Uint8Array>;\n targets: readonly DocumentContentKeyTarget[];\n}): Promise<DocumentContentKeyTargetEnvelope[]> {\n return Promise.all(\n sortDocumentTargets(input.targets).map(async (target) => {\n const targetKek = input.keksByEpochId.get(target.containerKeyEpochId);\n if (!targetKek) {\n throw new Error(\n `Document target KEK could not be unwrapped for ${describeDocumentTargetKek(target)}`,\n );\n }\n\n const wrapped = await wrapContentKey(input.contentKey, targetKek, {\n kind: \"Document\",\n objectId: input.documentId,\n contentKeyEpoch: input.contentKeyEpoch,\n containerId: target.containerId,\n containerKeyEpochId: target.containerKeyEpochId,\n });\n return {\n ...target,\n wrappedKey: bytesToBase64(wrapped.ciphertext),\n wrappingMetadata: {\n suite: DOCUMENT_CONTENT_KEY_WRAP_SUITE,\n iv: bytesToBase64(wrapped.iv),\n },\n };\n }),\n );\n}\n\n// Resolve the organization a link/unlink mutation belongs to: the document's\n// own org (from its manifest), which must equal the target container's org —\n// both are owned by the same organization. The acting member's personal org is\n// intentionally not part of this check; a member may link documents within any\n// org they belong to. Returns the document org so the plan stamps it onto the\n// signed event and manifest rather than the author's org.\nasync function resolveDocumentLinkSetMutationOrganization(input: {\n targetContainerProjection: ContainerWriterProjectionResponse;\n writerProjection: DocumentWriterProjectionResponse;\n}): Promise<string> {\n const manifestIdentity = await assertDocumentManifestBundleConsistent({\n bundle: input.writerProjection.documentManifest,\n label: \"Document link-set manifest\",\n });\n if (\n manifestIdentity.organizationId !==\n input.targetContainerProjection.organizationId\n ) {\n throw new Error(\"Document target container organization mismatch\");\n }\n\n return manifestIdentity.organizationId;\n}\n\nfunction readDocumentLinkSetPreviousEpoch(\n writerProjection: DocumentWriterProjectionResponse,\n): number {\n const previousState = writerProjection.documentManifest.state;\n const previousEpoch = isPlainRecord(previousState)\n ? Reflect.get(previousState, \"epoch\")\n : undefined;\n if (\n typeof previousEpoch !== \"number\" ||\n !Number.isInteger(previousEpoch) ||\n previousEpoch <= 0\n ) {\n throw new Error(\"Document link-set previous epoch is invalid\");\n }\n\n return previousEpoch;\n}\n\nasync function buildDocumentLinkSetMutationPlan({\n author,\n blobRewraps,\n contentKeyEpoch,\n eventId = crypto.randomUUID(),\n operation,\n signedAt = new Date().toISOString(),\n targetContainerProjection,\n targetEnvelopes,\n writerProjection,\n}: BuildDocumentLinkSetMutationPlanInput): Promise<DocumentLinkSetMutationPlan> {\n const organizationId = await resolveDocumentLinkSetMutationOrganization({\n targetContainerProjection,\n writerProjection,\n });\n const targetState = deriveDocumentLinkSetTargetState({\n operation,\n targetContainerProjection,\n writerProjection,\n });\n const targetEnvelopesForRequest = mergeTargetEnvelopes(\n targetState.targets,\n targetEnvelopes,\n );\n const targetContainerPathRefs = containerPathRefs(\n targetContainerProjection.path,\n );\n const eventPlan = await buildDocumentLinkSetEventPlan({\n author,\n blobRewraps,\n eventId,\n operation,\n organizationId,\n signedAt,\n targetContainerPathRefs,\n targetState,\n writerProjection,\n });\n const previousEpoch = readDocumentLinkSetPreviousEpoch(writerProjection);\n\n const state: DocumentLinkSetManifestState = {\n version: 1,\n documentId: writerProjection.documentId,\n organizationId,\n epoch: previousEpoch + 1,\n previousManifestHash: writerProjection.documentManifest.manifestHash,\n eventHash: eventPlan.eventHash,\n linkedContainerIds: [...targetState.linkedContainerIds],\n };\n const manifest = await deriveDocumentLinkSetManifest(state);\n const manifestHash = await computeAccessManifestHash(manifest);\n const targetHash = await computeDocumentContentKeyTargetHash(\n targetState.targets,\n );\n\n return {\n body: eventPlan.body,\n contentKeyEpoch,\n documentId: writerProjection.documentId,\n event: eventPlan.event,\n eventHash: eventPlan.eventHash,\n manifest,\n manifestHash,\n operation,\n request: {\n event: readCanonicalRecord(eventPlan.event, \"Document link-set event\"),\n body: readCanonicalRecord(eventPlan.body, \"Document link-set body\"),\n expectedManifestHash: manifestHash,\n manifest: readCanonicalRecord(manifest, \"Document link-set manifest\"),\n targetContainerPathRefs,\n authorizingContainerPathRefs: eventPlan.authorizingContainerPathRefs,\n contentKeyBundle: {\n contentKeyEpoch,\n linkSetManifestHash: manifestHash,\n targetHash,\n targets: targetEnvelopesForRequest,\n },\n },\n state,\n targetHash,\n targets: sortDocumentTargets(targetState.targets),\n };\n}\n\nexport async function buildMaterializedDocumentLinkSetMutationPlan(\n input: {\n author: DocumentCreateAuthor;\n expectedSubtreeRoot?: SubtreePurgeRoot | undefined;\n prepareBlobRewraps: (\n targets: readonly DocumentContentKeyTarget[],\n ) => Promise<BuildDocumentLinkSetMutationPlanInput[\"blobRewraps\"]>;\n contentKey?: Uint8Array | undefined;\n eventId?: string | undefined;\n execSql?: ExecSql | undefined;\n operation: DocumentLinkSetMutationOperation;\n signedAt?: string | undefined;\n targetContainerProjection: ContainerWriterProjectionResponse;\n targetSecretKey: Uint8Array;\n writerProjection: DocumentWriterProjectionResponse;\n } & ProjectionVerificationOptions,\n): Promise<MaterializedDocumentLinkSetMutationPlan> {\n const verificationOptions = projectionVerificationOptions(input);\n const principalPolicyCache: PrincipalPolicyCache = new Map();\n await assertDocumentWriterProjectionConsistent(input.writerProjection, {\n execSql: input.execSql,\n principalPolicyCache,\n ...verificationOptions,\n });\n await verifyDocumentLinkSetCurrentPolicies({\n execSql: input.execSql,\n principalPolicyCache,\n targetContainerProjection: input.targetContainerProjection,\n writerProjection: input.writerProjection,\n ...verificationOptions,\n });\n assertSubtreePurgePath(\n input.targetContainerProjection.path,\n input.expectedSubtreeRoot,\n );\n if (input.resolveProjectionUserKey)\n assertDocumentLinkAuthorAccess({\n ...input,\n principalPolicies: [...principalPolicyCache.values()],\n });\n const targetState = deriveDocumentLinkSetTargetState({\n operation: input.operation,\n targetContainerProjection: input.targetContainerProjection,\n writerProjection: input.writerProjection,\n });\n assertLinkSetWriteKeksCurrent(input, targetState.linkedContainerIds);\n const currentContentKey = await unwrapDocumentContentKeyFromWriterProjection({\n execSql: input.execSql,\n secretKey: input.targetSecretKey,\n writerProjection: input.writerProjection,\n ...verificationOptions,\n });\n const contentKeyRotated = input.operation === \"unlink\";\n const contentKey = contentKeyRotated\n ? (input.contentKey ?? crypto.getRandomValues(new Uint8Array(32)))\n : currentContentKey;\n if (contentKey.byteLength !== 32) {\n throw new Error(\"Document content key must be 32 bytes\");\n }\n // A link carries the existing envelopes forward at the same epoch; an\n // unlink rotates to a fresh key at the next one.\n const contentKeyEpoch =\n input.writerProjection.contentKeyBundle.contentKeyEpoch +\n (contentKeyRotated ? 1 : 0);\n const targetEnvelopes = await buildLinkSetTargetEnvelopes(input, {\n contentKey,\n contentKeyEpoch,\n targetState,\n });\n\n const plan = await buildDocumentLinkSetMutationPlan({\n author: input.author,\n blobRewraps: await input.prepareBlobRewraps(targetState.targets),\n contentKeyEpoch,\n eventId: input.eventId,\n operation: input.operation,\n signedAt: input.signedAt,\n targetContainerProjection: input.targetContainerProjection,\n targetEnvelopes,\n writerProjection: input.writerProjection,\n });\n\n return {\n contentKey,\n contentKeyRotated,\n plan,\n };\n}\n\nasync function buildLinkSetTargetEnvelopes(\n input: Parameters<typeof buildMaterializedDocumentLinkSetMutationPlan>[0],\n wrap: {\n contentKey: Uint8Array;\n contentKeyEpoch: number;\n targetState: ReturnType<typeof deriveDocumentLinkSetTargetState>;\n },\n): Promise<DocumentContentKeyTargetEnvelope[]> {\n const verificationOptions = projectionVerificationOptions(input);\n const sealing = {\n contentKey: wrap.contentKey,\n contentKeyEpoch: wrap.contentKeyEpoch,\n documentId: input.writerProjection.documentId,\n };\n if (input.operation === \"link\") {\n return [\n ...input.writerProjection.contentKeyBundle.targets,\n ...(await wrapDocumentContentKeyForTargets({\n ...sealing,\n keksByEpochId: await unwrapContainerKekPath({\n execSql: input.execSql,\n projection: input.targetContainerProjection,\n secretKey: input.targetSecretKey,\n ...verificationOptions,\n }),\n targets: [wrap.targetState.target],\n })),\n ];\n }\n return wrapDocumentContentKeyForTargets({\n ...sealing,\n keksByEpochId: (\n await collectContainerKeksForDocumentSync({\n execSql: input.execSql,\n secretKey: input.targetSecretKey,\n writerProjection: input.writerProjection,\n ...verificationOptions,\n })\n ).keksByEpochId,\n // The rotated key is wrapped only to verified current heads of the\n // remaining linked containers, never to a server-listed epoch.\n targets: verifiedDocumentWrapTargets({\n linkedContainerIds: wrap.targetState.linkedContainerIds,\n serverTargets: wrap.targetState.targets,\n writerProjection: input.writerProjection,\n }),\n });\n}\n\nfunction assertLinkSetWriteKeksCurrent(\n input: Pick<\n Parameters<typeof buildMaterializedDocumentLinkSetMutationPlan>[0],\n \"writerProjection\" | \"targetContainerProjection\" | \"operation\"\n >,\n linkedContainerIds: readonly string[],\n): void {\n // Unlink can escape a stale branch; only recipients of the successor key must be current.\n assertDocumentKekPathsCurrent(\n input.writerProjection,\n new Set(linkedContainerIds),\n );\n if (input.operation === \"link\") {\n assertContainerKekPathCurrent(\n input.targetContainerProjection.containerKeks,\n );\n }\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"linkSetAuthority.js","sourceRoot":"","sources":["linkSetAuthority.ts"],"names":[],"mappings":"AAIA,OAAO,EACL,2BAA2B,EAC3B,0BAA0B,GAC3B,MAAM,2CAA2C,CAAC;AACnD,OAAO,EAAE,0CAA0C,EAAE,MAAM,wCAAwC,CAAC;AAEpG,OAAO,EAEL,yBAAyB,GAC1B,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EACL,iDAAiD,GAElD,MAAM,yCAAyC,CAAC;AACjD,OAAO,EAAE,4BAA4B,EAAE,MAAM,sEAAsE,CAAC;AACpH,OAAO,EAAE,uCAAuC,EAAE,MAAM,+CAA+C,CAAC;AAIxG,iFAAiF;AACjF,MAAM,UAAU,8BAA8B,CAAC,KAK9C;IACC,MAAM,MAAM,GAAG;QACb,GAAG,KAAK,CAAC,MAAM;QACf,cAAc,EAAE,KAAK,CAAC,yBAAyB,CAAC,cAAc;KAC/D,CAAC;IACF,MAAM,UAAU,GAAG;QACjB,MAAM;QACN,aAAa,EAAE,OAAgB;QAC/B,iBAAiB,EAAE,KAAK,CAAC,iBAAiB;KAC3C,CAAC;IACF,2BAA2B,CAAC;QAC1B,GAAG,UAAU;QACb,UAAU,EAAE,KAAK,CAAC,yBAAyB;KAC5C,CAAC,CAAC;IACH,MAAM,MAAM,GAAG,0CAA0C,CACvD,KAAK,CAAC,gBAAgB,CACvB,CAAC;IACF,KAAK,MAAM,UAAU,IAAI,4BAA4B,CACnD,KAAK,CAAC,gBAAgB,CACvB,EAAE,CAAC;QACF,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,WAAW,CAAC;YAAE,SAAS;QACvD,IAAI,CAAC;YACH,2BAA2B,CAAC,EAAE,GAAG,UAAU,EAAE,UAAU,EAAE,CAAC,CAAC;YAC3D,OAAO;QACT,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,CAAC,KAAK,YAAY,0BAA0B,CAAC;gBAAE,MAAM,KAAK,CAAC;QAClE,CAAC;IACH,CAAC;IACD,MAAM,IAAI,0BAA0B,CAClC,+DAA+D,CAChE,CAAC;AACJ,CAAC;AAED,8EAA8E;AAC9E,MAAM,CAAC,KAAK,UAAU,oCAAoC,CACxD,KAKiC;IAEjC,yBAAyB,CAAC,KAAK,EAAE,oCAAoC,CAAC,CAAC;IACvE,IAAI,KAAK,CAAC,sBAAsB,KAAK,IAAI;QAAE,OAAO;IAClD,IAAI,CAAC;QACH,KAAK,MAAM,UAAU,IAAI;YACvB,KAAK,CAAC,yBAAyB;YAC/B,GAAG,4BAA4B,CAAC,KAAK,CAAC,gBAAgB,CAAC;SACxD,EAAE,CAAC;YACF,MAAM,iDAAiD,CAAC;gBACtD,OAAO,EAAE,KAAK,CAAC,OAAO;gBACtB,oBAAoB,EAAE,KAAK,CAAC,oBAAoB;gBAChD,UAAU;gBACV,cAAc,EAAE,KAAK,CAAC,wBAAwB;gBAC9C,YAAY,EAAE,KAAK,CAAC,YAAY;gBAChC,+BAA+B,EAAE,KAAK,CAAC,+BAA+B;aACvE,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,uCAAuC,CACrC,KAAK,EACL,sDAAsD,CACvD,CAAC;IACJ,CAAC;AACH,CAAC","sourcesContent":["import type {\n ContainerWriterProjectionResponse,\n DocumentWriterProjectionResponse,\n} from \"@tearleads/validators/response\";\nimport {\n assertContainerAuthorAccess,\n ContainerAuthorAccessError,\n} from \"../../data/containers/shared/authorAccess\";\nimport { readLinkedContainerIdsFromDocumentManifest } from \"../../data/documents/shared/projection\";\nimport type { DocumentCreateAuthor } from \"../../data/documents/shared/types\";\nimport {\n type ProjectionVerificationOptions,\n resolveProjectionVerifier,\n} from \"../../data/documents/shared/types\";\nimport {\n collectContainerWriterProjectionPrincipalPolicies,\n type PrincipalPolicyCache,\n} from \"../../data/keyingProjectionVerification\";\nimport { documentContainerProjections } from \"../../data/keyingProjectionVerification/documentContainerProjections\";\nimport { throwKeyingVerificationErrorWithContext } from \"../../data/keyingProjectionVerification/error\";\nimport type { PrincipalPolicyCheckpointEvidence } from \"../../data/principals/principalPolicyEvidence\";\nimport type { ExecSql } from \"../../data/sqlite/sqlSchema\";\n\n/** Both paths have been verified; a readable proof does not authorize a link. */\nexport function assertDocumentLinkAuthorAccess(input: {\n author: DocumentCreateAuthor;\n principalPolicies: readonly PrincipalPolicyCheckpointEvidence[];\n targetContainerProjection: ContainerWriterProjectionResponse;\n writerProjection: DocumentWriterProjectionResponse;\n}): void {\n const author = {\n ...input.author,\n organizationId: input.targetContainerProjection.organizationId,\n };\n const permission = {\n author,\n minimumAccess: \"write\" as const,\n principalPolicies: input.principalPolicies,\n };\n assertContainerAuthorAccess({\n ...permission,\n projection: input.targetContainerProjection,\n });\n const linked = readLinkedContainerIdsFromDocumentManifest(\n input.writerProjection,\n );\n for (const projection of documentContainerProjections(\n input.writerProjection,\n )) {\n if (!linked.includes(projection.containerId)) continue;\n try {\n assertContainerAuthorAccess({ ...permission, projection });\n return;\n } catch (error) {\n if (!(error instanceof ContainerAuthorAccessError)) throw error;\n }\n }\n throw new ContainerAuthorAccessError(\n \"Document signer lacks write access through a linked container\",\n );\n}\n\n/** Current write authorization needs full policies for the readable paths. */\nexport async function verifyDocumentLinkSetCurrentPolicies(\n input: {\n execSql?: ExecSql | undefined;\n principalPolicyCache: PrincipalPolicyCache;\n targetContainerProjection: ContainerWriterProjectionResponse;\n writerProjection: DocumentWriterProjectionResponse;\n } & ProjectionVerificationOptions,\n): Promise<void> {\n resolveProjectionVerifier(input, \"Document link-set current policies\");\n if (input.trustedLocalProjection === true) return;\n try {\n for (const projection of [\n input.targetContainerProjection,\n ...documentContainerProjections(input.writerProjection),\n ]) {\n await collectContainerWriterProjectionPrincipalPolicies({\n execSql: input.execSql,\n principalPolicyCache: input.principalPolicyCache,\n projection,\n resolveUserKey: input.resolveProjectionUserKey,\n stillCurrent: input.stillCurrent,\n warmReferencedPrincipalPolicies: input.warmReferencedPrincipalPolicies,\n });\n }\n } catch (error) {\n throwKeyingVerificationErrorWithContext(\n error,\n \"Document link-set current policy verification failed\",\n );\n }\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"linkSetBlobRewraps.js","sourceRoot":"","sources":["linkSetBlobRewraps.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,2BAA2B,EAG3B,cAAc,GACf,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAMpD,OAAO,EACL,kCAAkC,EAClC,sBAAsB,GACvB,MAAM,wCAAwC,CAAC;AAChD,OAAO,EACL,gBAAgB,EAChB,SAAS,GACV,MAAM,qCAAqC,CAAC;AAK7C,OAAO,EAAE,6BAA6B,EAAE,MAAM,mCAAmC,CAAC;AAClF,OAAO,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AACpE,OAAO,EAAE,gCAAgC,EAAE,MAAM,yCAAyC,CAAC;AAC3F,OAAO,EAAE,oCAAoC,EAAE,MAAM,+DAA+D,CAAC;AACrH,OAAO,EAAE,4BAA4B,EAAE,MAAM,sEAAsE,CAAC;AACpH,OAAO,EAAE,mCAAmC,EAAE,MAAM,+CAA+C,CAAC;AAEpG,OAAO,EAAE,2BAA2B,EAAE,MAAM,8BAA8B,CAAC;AAC3E,OAAO,EAAE,gCAAgC,EAAE,MAAM,qCAAqC,CAAC;AACvF,OAAO,EAAE,wBAAwB,EAAE,MAAM,yCAAyC,CAAC;AAQnF,mFAAmF;AACnF,MAAM,CAAC,KAAK,UAAU,8BAA8B,CAClD,KAOiC;IAEjC,MAAM,UAAU,GAAG,KAAK,CAAC,gBAAgB,CAAC,UAAU,CAAC;IACrD,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,SAAS,CAAC,uBAAuB,CAAC,UAAU,CAAC,CAAC;IAC3E,2EAA2E;IAC3E,0EAA0E;IAC1E,2EAA2E;IAC3E,IAAI,CAAC,QAAQ;QACX,MAAM,IAAI,oCAAoC,CAC5C,oDAAoD,CACrD,CAAC;IACJ,mCAAmC,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;IACxD,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IACrC,MAAM,IAAI,GAAG,MAAM,iBAAiB,CAAC,KAAK,CAAC,CAAC;IAC5C,MAAM,eAAe,GAAG,gCAAgC,CACtD,KAAK,CAAC,SAAS,EACf,UAAU,CACX,CAAC;IACF,MAAM,cAAc,GAAG,2BAA2B,CAChD,KAAK,CAAC,SAAS,EACf,UAAU,EACV,wBAAwB,CACzB,CAAC;IACF,MAAM,YAAY,GAAG,IAAI,GAAG,EAAsB,CAAC;IACnD,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,MAAM,YAAY,GAAG;YACnB,OAAO;YACP,kBAAkB,EAAE,UAAU;YAC9B,cAAc,EAAE,OAAO,CAAC,MAAM;YAC9B,OAAO,EAAE,KAAK,CAAC,OAAO;YACtB,wBAAwB,EAAE,gCAAgC,CACxD,KAAK,CAAC,wBAAwB,EAC9B,mBAAmB,CACpB;YACD,eAAe,EAAE,KAAK,CAAC,eAAe;YACtC,YAAY,EAAE,KAAK,CAAC,YAAY;YAChC,+BAA+B,EAAE,KAAK,CAAC,+BAA+B;YACtE,gBAAgB,EAAE,KAAK,CAAC,gBAAgB;SACzC,CAAC;QACF,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CACjC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,CAAC,CACzD,CAAC;QACF,MAAM,UAAU,GAAG,QAAQ,CAAC,CAAC,CAAC,MAAM,eAAe,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QACzE,IAAI,CAAC,QAAQ;YAAE,MAAM,cAAc,CAAC,YAAY,CAAC,CAAC;QAClD,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,GAAG,CAC/B,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE;YACjC,MAAM,QAAQ,GAAG,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC;YAC7D,IAAI,QAAQ;gBACV,OAAO;oBACL,GAAG,QAAQ;oBACX,GAAG,MAAM;oBACT,gBAAgB,EAAE,iBAAiB,CACjC,QAAQ,CAAC,gBAAgB,EACzB,0BAA0B,CAC3B;iBACF,CAAC;YACJ,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC;YACxC,IAAI,CAAC,GAAG;gBACN,MAAM,IAAI,KAAK,CACb,iEAAiE,CAClE,CAAC;YACJ,IAAI,CAAC,UAAU;gBACb,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;YAC3D,OAAO,oBAAoB,CAAC;gBAC1B,OAAO;gBACP,UAAU;gBACV,UAAU;gBACV,GAAG;gBACH,MAAM;aACP,CAAC,CAAC;QACL,CAAC,CAAC,CACH,CAAC;QACF,MAAM,MAAM,GAAG,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI;YACjD,MAAM,EAAE,OAAO,CAAC,MAAM;YACtB,eAAe,EAAE,OAAO,CAAC,gBAAgB,CAAC,eAAe;YACzD,OAAO,EAAE,EAAE;SACZ,CAAC;QACF,IAAI,MAAM,CAAC,eAAe,KAAK,OAAO,CAAC,gBAAgB,CAAC,eAAe;YACrE,MAAM,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAC;QACvE,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,CAAC;QAChC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACzC,mCAAmC,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;IAC1D,CAAC;IACD,OAAO,CAAC,GAAG,YAAY,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;AACzD,CAAC;AAED,KAAK,UAAU,oBAAoB,CAAC,KAMnC;IACC,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,KAAK,CAAC;IAClC,MAAM,OAAO,GAAG,MAAM,cAAc,CAAC,KAAK,CAAC,UAAU,EAAE,KAAK,CAAC,GAAG,EAAE;QAChE,IAAI,EAAE,MAAM;QACZ,QAAQ,EAAE,OAAO,CAAC,MAAM;QACxB,eAAe,EAAE,OAAO,CAAC,gBAAgB,CAAC,eAAe;QACzD,WAAW,EAAE,MAAM,CAAC,WAAW;QAC/B,mBAAmB,EAAE,MAAM,CAAC,mBAAmB;KAChD,CAAC,CAAC;IACH,OAAO;QACL,GAAG,MAAM;QACT,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,UAAU,EAAE,KAAK,CAAC,UAAU;QAC5B,UAAU,EAAE,aAAa,CAAC,OAAO,CAAC,UAAU,CAAC;QAC7C,gBAAgB,EAAE;YAChB,KAAK,EAAE,2BAA2B;YAClC,EAAE,EAAE,aAAa,CAAC,OAAO,CAAC,EAAE,CAAC;SAC9B;KACF,CAAC;AACJ,CAAC;AAED,SAAS,cAAc,CACrB,OAA8B,EAC9B,MAAgC,EAChC,UAAkB;IAElB,OAAO,OAAO,CAAC,gBAAgB,CAAC,OAAO,CAAC,IAAI,CAC1C,CAAC,SAAS,EAAE,EAAE,CACZ,SAAS,CAAC,SAAS,KAAK,OAAO,CAAC,SAAS;QACzC,SAAS,CAAC,UAAU,KAAK,UAAU;QACnC,SAAS,CAAC,WAAW,KAAK,MAAM,CAAC,WAAW;QAC5C,SAAS,CAAC,mBAAmB,KAAK,MAAM,CAAC,mBAAmB,CAC/D,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,iBAAiB,CAC9B,KAA2D;IAE3D,MAAM,IAAI,GAAG,IAAI,GAAG,EAAsB,CAAC;IAC3C,KAAK,MAAM,UAAU,IAAI;QACvB,GAAG,4BAA4B,CAAC,KAAK,CAAC,gBAAgB,CAAC;QACvD,KAAK,CAAC,yBAAyB;KAChC,EAAE,CAAC;QACF,MAAM,IAAI,GAAG,MAAM,sBAAsB,CAAC;YACxC,UAAU;YACV,SAAS,EAAE,KAAK,CAAC,eAAe;YAChC,OAAO,EAAE,KAAK,CAAC,OAAO;YACtB,GAAG,6BAA6B,CAAC,KAAK,CAAC;SACxC,CAAC,CAAC;QACH,yEAAyE;QACzE,8EAA8E;QAC9E,KAAK,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,UAAU,CAAC,aAAa,CAAC,OAAO,EAAE,EAAE,CAAC;YAC/D,MAAM,MAAM,GAAG,kCAAkC,CAAC;gBAChD,GAAG,UAAU;gBACb,WAAW,EAAE,IAAI,CAAC,WAAW;gBAC7B,IAAI,EAAE,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,GAAG,CAAC,CAAC;gBACzC,aAAa,EAAE,UAAU,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,GAAG,CAAC,CAAC;aAC5D,CAAC,CAAC;YACH,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,mBAAmB,CAAC,CAAC;YACjD,+DAA+D;YAC/D,IAAI,CAAC,GAAG;gBAAE,SAAS;YACnB,MAAM,EAAE,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC;YAC7B,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAC9B,IAAI,QAAQ;gBACV,gBAAgB,CACd,QAAQ,EACR,GAAG,EACH,sDAAsD,CACvD,CAAC;YACJ,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;QACpB,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,cAAc,CAAC,CAAqB,EAAE,CAAqB;IAClE,OAAO,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAChE,CAAC","sourcesContent":["import {\n BLOB_CONTENT_KEY_WRAP_SUITE,\n type DocumentContentKeyTarget,\n type DocumentLinkAccessEventBody,\n wrapContentKey,\n} from \"@tearleads/crypto\";\nimport { bytesToBase64 } from \"@tearleads/encoding\";\nimport type {\n BlobAttachmentSummary,\n ContainerWriterProjectionResponse,\n DocumentWriterProjectionResponse,\n} from \"@tearleads/validators/response\";\nimport {\n deriveDocumentTargetFromProjection,\n unwrapContainerKekPath,\n} from \"../../data/documents/shared/projection\";\nimport {\n assertEqualBytes,\n targetKey,\n} from \"../../data/documents/shared/readers\";\nimport type {\n DocumentLinkSetMutationApi,\n ProjectionVerificationOptions,\n} from \"../../data/documents/shared/types\";\nimport { projectionVerificationOptions } from \"../../data/documents/shared/types\";\nimport { readCanonicalJson } from \"../../data/keying/canonicalJson\";\nimport { requireProjectionUserKeyResolver } from \"../../data/keyingProjectionVerification\";\nimport { ProjectionDependencyUnavailableError } from \"../../data/keyingProjectionVerification/dependencyUnavailable\";\nimport { documentContainerProjections } from \"../../data/keyingProjectionVerification/documentContainerProjections\";\nimport { assertProjectionVerificationCurrent } from \"../../data/keyingProjectionVerification/types\";\nimport type { ExecSql } from \"../../data/sqlite/sqlSchema\";\nimport { createAttachmentProofReader } from \"../blobs/attachmentDecryptor\";\nimport { createAttachmentKeyAuthenticator } from \"../blobs/attachmentKeyAuthenticator\";\nimport { verifyRetainedAttachment } from \"../blobs/retainedAttachmentVerification\";\n\ninterface BlobRewrap {\n blobId: string;\n contentKeyEpoch: number;\n targets: DocumentLinkAccessEventBody[\"blobRewraps\"][number][\"targets\"][number][];\n}\n\n/** Authenticate the existing bytes before propagating their DEK to a new scope. */\nexport async function prepareDocumentLinkBlobRewraps(\n input: {\n apiClient: DocumentLinkSetMutationApi;\n execSql: ExecSql;\n targetContainerProjection: ContainerWriterProjectionResponse;\n targetSecretKey: Uint8Array;\n targets: readonly DocumentContentKeyTarget[];\n writerProjection: DocumentWriterProjectionResponse;\n } & ProjectionVerificationOptions,\n): Promise<DocumentLinkAccessEventBody[\"blobRewraps\"]> {\n const documentId = input.writerProjection.documentId;\n const bindings = await input.apiClient.listDocumentAttachments(documentId);\n // The API refuses the link unless every active binding is rewrapped, so an\n // unavailable listing (offline, or a 409 while a bind is mid-flight) is a\n // retryable availability failure of this mutation, not integrity evidence.\n if (!bindings)\n throw new ProjectionDependencyUnavailableError(\n \"Document attachments are unavailable for relinking\",\n );\n assertProjectionVerificationCurrent(input.stillCurrent);\n if (bindings.length === 0) return [];\n const keks = await collectRelinkKeks(input);\n const authenticateKey = createAttachmentKeyAuthenticator(\n input.apiClient,\n documentId,\n );\n const verifyRetained = createAttachmentProofReader(\n input.apiClient,\n documentId,\n verifyRetainedAttachment,\n );\n const rewrapByBlob = new Map<string, BlobRewrap>();\n for (const binding of bindings) {\n const verification = {\n binding,\n expectedDocumentId: documentId,\n expectedSlotId: binding.slotId,\n execSql: input.execSql,\n resolveProjectionUserKey: requireProjectionUserKeyResolver(\n input.resolveProjectionUserKey,\n \"Attachment relink\",\n ),\n targetSecretKey: input.targetSecretKey,\n stillCurrent: input.stillCurrent,\n warmReferencedPrincipalPolicies: input.warmReferencedPrincipalPolicies,\n writerProjection: input.writerProjection,\n };\n const needsKey = input.targets.some(\n (target) => !retainedTarget(binding, target, documentId),\n );\n const contentKey = needsKey ? await authenticateKey(verification) : null;\n if (!needsKey) await verifyRetained(verification);\n const targets = await Promise.all(\n input.targets.map(async (target) => {\n const previous = retainedTarget(binding, target, documentId);\n if (previous)\n return {\n ...previous,\n ...target,\n wrappingMetadata: readCanonicalJson(\n previous.wrappingMetadata,\n \"Attachment wrap metadata\",\n ),\n };\n const kek = keks.get(targetKey(target));\n if (!kek)\n throw new Error(\n \"Attachment destination is not a verified current container head\",\n );\n if (!contentKey)\n throw new Error(\"Attachment content key is unavailable\");\n return wrapBlobKeyForTarget({\n binding,\n contentKey,\n documentId,\n kek,\n target,\n });\n }),\n );\n const rewrap = rewrapByBlob.get(binding.blobId) ?? {\n blobId: binding.blobId,\n contentKeyEpoch: binding.contentKeyBundle.contentKeyEpoch,\n targets: [],\n };\n if (rewrap.contentKeyEpoch !== binding.contentKeyBundle.contentKeyEpoch)\n throw new Error(\"Attachment content epoch changed during relinking\");\n rewrap.targets.push(...targets);\n rewrapByBlob.set(binding.blobId, rewrap);\n assertProjectionVerificationCurrent(input.stillCurrent);\n }\n return [...rewrapByBlob.values()].sort(compareBlobIds);\n}\n\nasync function wrapBlobKeyForTarget(input: {\n binding: BlobAttachmentSummary;\n contentKey: Uint8Array;\n documentId: string;\n kek: Uint8Array;\n target: DocumentContentKeyTarget;\n}) {\n const { binding, target } = input;\n const wrapped = await wrapContentKey(input.contentKey, input.kek, {\n kind: \"Blob\",\n objectId: binding.blobId,\n contentKeyEpoch: binding.contentKeyBundle.contentKeyEpoch,\n containerId: target.containerId,\n containerKeyEpochId: target.containerKeyEpochId,\n });\n return {\n ...target,\n bindingId: binding.bindingId,\n documentId: input.documentId,\n wrappedKey: bytesToBase64(wrapped.ciphertext),\n wrappingMetadata: {\n suite: BLOB_CONTENT_KEY_WRAP_SUITE,\n iv: bytesToBase64(wrapped.iv),\n },\n };\n}\n\nfunction retainedTarget(\n binding: BlobAttachmentSummary,\n target: DocumentContentKeyTarget,\n documentId: string,\n) {\n return binding.contentKeyBundle.targets.find(\n (candidate) =>\n candidate.bindingId === binding.bindingId &&\n candidate.documentId === documentId &&\n candidate.containerId === target.containerId &&\n candidate.containerKeyEpochId === target.containerKeyEpochId,\n );\n}\n\nasync function collectRelinkKeks(\n input: Parameters<typeof prepareDocumentLinkBlobRewraps>[0],\n): Promise<Map<string, Uint8Array>> {\n const keks = new Map<string, Uint8Array>();\n for (const projection of [\n ...documentContainerProjections(input.writerProjection),\n input.targetContainerProjection,\n ]) {\n const keys = await unwrapContainerKekPath({\n projection,\n secretKey: input.targetSecretKey,\n execSql: input.execSql,\n ...projectionVerificationOptions(input),\n });\n // Every node of this verified path has a current signed head. Historical\n // keyring entries may open source bytes, but never enter the destination map.\n for (const [index, head] of projection.containerKeks.entries()) {\n const target = deriveDocumentTargetFromProjection({\n ...projection,\n containerId: head.containerId,\n path: projection.path.slice(0, index + 1),\n containerKeks: projection.containerKeks.slice(0, index + 1),\n });\n const key = keys.get(target.containerKeyEpochId);\n // A direct child grantee need not possess any ancestor secret.\n if (!key) continue;\n const id = targetKey(target);\n const previous = keks.get(id);\n if (previous)\n assertEqualBytes(\n previous,\n key,\n \"Attachment link projections contain conflicting KEKs\",\n );\n keks.set(id, key);\n }\n }\n return keks;\n}\n\nfunction compareBlobIds(a: { blobId: string }, b: { blobId: string }): number {\n return a.blobId < b.blobId ? -1 : a.blobId > b.blobId ? 1 : 0;\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"linkSetProjectionSeed.js","sourceRoot":"","sources":["linkSetProjectionSeed.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,wCAAwC,EAAE,MAAM,wCAAwC,CAAC;AAElG,OAAO,EAAE,6BAA6B,EAAE,MAAM,uEAAuE,CAAC;AAUtH,SAAS,qBAAqB,CAC5B,OAAoD;IAEpD,MAAM,MAAM,GAAG,IAAI,GAAG,EAA4C,CAAC;IACnE,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,YAAY,CAAC,EAAE,CAAC;YACrC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;QAC1C,CAAC;IACH,CAAC;IAED,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;AAC9B,CAAC;AAED,SAAS,mBAAmB,CAC1B,KAA+D;IAE/D,MAAM,UAAU,GAAG,IAAI,GAAG,EAA8C,CAAC;IACzE,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,QAAQ,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,YAAY,CAAC;QAC3C,IAAI,CAAC,QAAQ,IAAI,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC1C,SAAS;QACX,CAAC;QAED,UAAU,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;IACtC,CAAC;IAED,OAAO,CAAC,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC,CAAC;AAClC,CAAC;AAED,SAAS,kCAAkC,CACzC,UAAuC;IAEvC,OAAO,UAAU,CAAC,aAAa,CAAC,OAAO,CACrC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,wBAAwB,CACtC,CAAC;AACJ,CAAC;AAED,SAAS,gCAAgC,CACvC,UAA4C;IAE5C,OAAO,mBAAmB,CAAC;QACzB,GAAG,UAAU,CAAC,8BAA8B;QAC5C,GAAG,UAAU,CAAC,yBAAyB,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC;KACjE,CAAC,CAAC;AACL,CAAC;AAED,SAAS,kCAAkC,CAAC,KAG3C;IACC,MAAM,mBAAmB,GAAG,gCAAgC,CAC1D,KAAK,CAAC,eAAe,CACtB,CAAC;IACF,MAAM,oCAAoC,GACxC,KAAK,CAAC,eAAe,CAAC,yBAAyB,CAAC;IAElD,OAAO,qBAAqB,CAAC;QAC3B,GAAG,KAAK,CAAC,eAAe,CAAC,gCAAgC;QACzD,GAAG,mBAAmB,CAAC,IAAI,EAAE;QAC7B,GAAG,oCAAoC,CAAC,OAAO,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC;YAC9D,GAAG,UAAU,CAAC,IAAI;YAClB,GAAG,kCAAkC,CAAC,UAAU,CAAC;SAClD,CAAC;QACF,GAAG,KAAK,CAAC,yBAAyB,CAAC,IAAI;QACvC,GAAG,kCAAkC,CAAC,KAAK,CAAC,yBAAyB,CAAC;KACvE,CAAC,CAAC;AACL,CAAC;AAED;;;;;;;;;GASG;AACH,SAAS,mCAAmC,CAAC,KAM5C;IACC,2EAA2E;IAC3E,8DAA8D;IAC9D,MAAM,aAAa,GAAG,KAAK,CAAC,eAAe,CAAC,yBAAyB,CAAC,MAAM,CAC1E,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,WAAW,KAAK,KAAK,CAAC,iBAAiB,CACvD,CAAC;IACF,MAAM,yBAAyB,GAC7B,KAAK,CAAC,SAAS,KAAK,MAAM;QACxB,CAAC,CAAC,CAAC,GAAG,aAAa,EAAE,KAAK,CAAC,yBAAyB,CAAC;QACrD,CAAC,CAAC,aAAa,CAAC;IACpB,MAAM,8BAA8B,GAAG,mBAAmB,CAAC;QACzD,GAAG,gCAAgC,CAAC,KAAK,CAAC,eAAe,CAAC;QAC1D,KAAK,CAAC,yBAAyB,CAAC,IAAI;KACrC,CAAC,CAAC;IACH,OAAO;QACL,cAAc,EAAE,6BAA6B,CAAC;YAC5C,KAAK,CAAC,eAAe,CAAC,cAAc;YACpC,KAAK,CAAC,yBAAyB,CAAC,cAAc;SAC/C,CAAC;QACF,yBAAyB;QACzB,gBAAgB,EAAE,KAAK,CAAC,QAAQ,CAAC,gBAAgB;QACjD,UAAU,EAAE,KAAK,CAAC,QAAQ,CAAC,EAAE;QAC7B,gCAAgC,EAAE,kCAAkC,CAAC;YACnE,eAAe,EAAE,KAAK,CAAC,eAAe;YACtC,yBAAyB,EAAE,KAAK,CAAC,yBAAyB;SAC3D,CAAC;QACF,kBAAkB,EAAE,KAAK,CAAC,QAAQ,CAAC,kBAAkB;QACrD,gBAAgB,EAAE,KAAK,CAAC,QAAQ,CAAC,cAAc;QAC/C,8BAA8B;QAC9B,uBAAuB,EAAE;YACvB,KAAK,CAAC,eAAe,CAAC,gBAAgB;YACtC,GAAG,KAAK,CAAC,eAAe,CAAC,uBAAuB;SACjD;KACF,CAAC;AACJ,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,2BAA2B,CAAC,KASjD;IACC,MAAM,UAAU,GAAG,mCAAmC,CAAC;QACrD,SAAS,EAAE,KAAK,CAAC,SAAS;QAC1B,eAAe,EAAE,KAAK,CAAC,eAAe;QACtC,QAAQ,EAAE,KAAK,CAAC,QAAQ;QACxB,iBAAiB,EAAE,KAAK,CAAC,iBAAiB;QAC1C,yBAAyB,EAAE,KAAK,CAAC,yBAAyB;KAC3D,CAAC,CAAC;IACH,IAAI,CAAC;QACH,MAAM,wCAAwC,CAAC,UAAU,EAAE;YACzD,OAAO,EAAE,KAAK,CAAC,OAAO;YACtB,sBAAsB,EAAE,IAAI;SAC7B,CAAC,CAAC;IACL,CAAC;IAAC,MAAM,CAAC;QACP,OAAO;IACT,CAAC;IACD,IAAI,KAAK,CAAC,YAAY,EAAE,EAAE,KAAK,KAAK;QAAE,OAAO;IAC7C,KAAK,CAAC,SAAS,CAAC,6BAA6B,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,EAAE,UAAU,CAAC,CAAC;AAC/E,CAAC","sourcesContent":["import type {\n AccessManifestBundleWireResponse,\n ContainerKeyingPathResponse,\n ContainerWriterProjectionResponse,\n DocumentLinkSetMutationResponse,\n DocumentWriterProjectionResponse,\n} from \"@tearleads/validators/response\";\nimport { assertDocumentWriterProjectionConsistent } from \"../../data/documents/shared/projection\";\nimport type { DocumentLinkSetMutationOperation } from \"../../data/documents/shared/types\";\nimport { mergeProjectionPolicyEvidence } from \"../../data/keyingProjectionVerification/mergeProjectionPolicyEvidence\";\nimport type { ExecSql } from \"../../data/sqlite/sqlSchema\";\n\ninterface DocumentLinkSetProjectionSeedApi {\n primeDocumentWriterProjection(\n documentId: string,\n projection: DocumentWriterProjectionResponse,\n ): void;\n}\n\nfunction uniqueManifestBundles(\n bundles: readonly AccessManifestBundleWireResponse[],\n): AccessManifestBundleWireResponse[] {\n const byHash = new Map<string, AccessManifestBundleWireResponse>();\n for (const bundle of bundles) {\n if (!byHash.has(bundle.manifestHash)) {\n byHash.set(bundle.manifestHash, bundle);\n }\n }\n\n return [...byHash.values()];\n}\n\nfunction uniqueManifestPaths(\n paths: readonly (readonly AccessManifestBundleWireResponse[])[],\n): AccessManifestBundleWireResponse[][] {\n const byLeafHash = new Map<string, AccessManifestBundleWireResponse[]>();\n for (const path of paths) {\n const leafHash = path.at(-1)?.manifestHash;\n if (!leafHash || byLeafHash.has(leafHash)) {\n continue;\n }\n\n byLeafHash.set(leafHash, [...path]);\n }\n\n return [...byLeafHash.values()];\n}\n\nfunction containerProjectionManifestHistory(\n projection: ContainerKeyingPathResponse,\n): AccessManifestBundleWireResponse[] {\n return projection.containerKeks.flatMap(\n (kek) => kek.containerManifestHistory,\n );\n}\n\nfunction documentProjectionContainerPaths(\n projection: DocumentWriterProjectionResponse,\n): AccessManifestBundleWireResponse[][] {\n return uniqueManifestPaths([\n ...projection.documentManifestContainerPaths,\n ...projection.authorizingContainerPaths.map((path) => path.path),\n ]);\n}\n\nfunction documentProjectionContainerHistory(input: {\n priorProjection: DocumentWriterProjectionResponse;\n targetContainerProjection: ContainerWriterProjectionResponse;\n}): AccessManifestBundleWireResponse[] {\n const priorContainerPaths = documentProjectionContainerPaths(\n input.priorProjection,\n );\n const priorAuthorizingContainerProjections =\n input.priorProjection.authorizingContainerPaths;\n\n return uniqueManifestBundles([\n ...input.priorProjection.documentContainerManifestHistory,\n ...priorContainerPaths.flat(),\n ...priorAuthorizingContainerProjections.flatMap((projection) => [\n ...projection.path,\n ...containerProjectionManifestHistory(projection),\n ]),\n ...input.targetContainerProjection.path,\n ...containerProjectionManifestHistory(input.targetContainerProjection),\n ]);\n}\n\n/**\n * Reconstruct the post-mutation writer projection from a link/unlink response.\n * The response carries the fresh manifest, content-key bundle, and KEK targets;\n * the authorizing container paths change by exactly one entry — link appends\n * the target container's projection, unlink drops it (keyed by containerId).\n * Link does not rotate the content key (only unlink does), but either way the\n * bundle/targets the next write needs come straight from the response. The\n * caller verifies this projection for internal consistency before seeding it,\n * so a wrong reconstruction is discarded rather than cached.\n */\nfunction linkSetWriterProjectionFromResponse(input: {\n operation: DocumentLinkSetMutationOperation;\n priorProjection: DocumentWriterProjectionResponse;\n response: DocumentLinkSetMutationResponse;\n targetContainerId: string;\n targetContainerProjection: ContainerWriterProjectionResponse;\n}): DocumentWriterProjectionResponse {\n // The target container's authorizing path is replaced wholesale: link adds\n // the fresh target projection back, unlink leaves it dropped.\n const retainedPaths = input.priorProjection.authorizingContainerPaths.filter(\n (path) => path.containerId !== input.targetContainerId,\n );\n const authorizingContainerPaths =\n input.operation === \"link\"\n ? [...retainedPaths, input.targetContainerProjection]\n : retainedPaths;\n const documentManifestContainerPaths = uniqueManifestPaths([\n ...documentProjectionContainerPaths(input.priorProjection),\n input.targetContainerProjection.path,\n ]);\n return {\n policyEvidence: mergeProjectionPolicyEvidence([\n input.priorProjection.policyEvidence,\n input.targetContainerProjection.policyEvidence,\n ]),\n authorizingContainerPaths,\n contentKeyBundle: input.response.contentKeyBundle,\n documentId: input.response.id,\n documentContainerManifestHistory: documentProjectionContainerHistory({\n priorProjection: input.priorProjection,\n targetContainerProjection: input.targetContainerProjection,\n }),\n documentKekTargets: input.response.documentKekTargets,\n documentManifest: input.response.accessManifest,\n documentManifestContainerPaths,\n documentManifestHistory: [\n input.priorProjection.documentManifest,\n ...input.priorProjection.documentManifestHistory,\n ],\n };\n}\n\n/**\n * Reconstruct and seed the post-mutation writer projection so the first read\n * after a link/unlink resolves locally instead of a cold GET. Gates the seed on\n * the projection's internal consistency (manifest hash ↔ content-key bundle ↔\n * KEK targets ↔ linked containers); on any mismatch the seed is skipped and the\n * next read falls back to a fetch — the seed is an optimization, never a\n * correctness dependency. The expensive per-path signature re-verification is\n * deliberately not run here: the server already verified the mutation, and the\n * next read re-verifies the projection before any write.\n */\nexport async function seedLinkSetWriterProjection(input: {\n apiClient: DocumentLinkSetProjectionSeedApi;\n execSql?: ExecSql | undefined;\n operation: DocumentLinkSetMutationOperation;\n priorProjection: DocumentWriterProjectionResponse;\n response: DocumentLinkSetMutationResponse;\n targetContainerId: string;\n targetContainerProjection: ContainerWriterProjectionResponse;\n stillCurrent?: (() => boolean) | undefined;\n}): Promise<void> {\n const projection = linkSetWriterProjectionFromResponse({\n operation: input.operation,\n priorProjection: input.priorProjection,\n response: input.response,\n targetContainerId: input.targetContainerId,\n targetContainerProjection: input.targetContainerProjection,\n });\n try {\n await assertDocumentWriterProjectionConsistent(projection, {\n execSql: input.execSql,\n trustedLocalProjection: true,\n });\n } catch {\n return;\n }\n if (input.stillCurrent?.() === false) return;\n input.apiClient.primeDocumentWriterProjection(input.response.id, projection);\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"linkSetRemote.js","sourceRoot":"","sources":["linkSetRemote.ts"],"names":[],"mappings":"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","sourcesContent":["import type { DocumentLinkSetMutationRequest } from \"@tearleads/validators/request\";\nimport type {\n ContainerWriterProjectionResponse,\n DocumentLinkSetMutationResponse,\n DocumentWriterProjectionResponse,\n} from \"@tearleads/validators/response\";\nimport { acknowledgeDocumentMutation } from \"../../data/documents/shared/mutationAcknowledgement\";\nimport { persistedDocumentLinkSetMutationStateFromResponse } from \"../../data/documents/shared/responses\";\nimport type {\n DocumentCreateAuthor,\n DocumentLinkSetFailureHandler,\n DocumentLinkSetMutationApi,\n DocumentLinkSetMutationFailure,\n DocumentLinkSetMutationOperation,\n DocumentSyncSubmitFailure,\n RelinkRemoteDocumentResult,\n} from \"../../data/documents/shared/types\";\nimport {\n nullOnProjectionVerificationCancellation,\n type ProjectionUserKeyResolver,\n type ReferencedPrincipalPolicyWarmer,\n requireProjectionUserKeyResolver,\n} from \"../../data/keyingProjectionVerification\";\nimport type { ExecSql } from \"../../data/sqlite/sqlSchema\";\nimport { recordDocumentAuthorAccessFailure } from \"./authorAccessFailure\";\nimport { buildMaterializedDocumentLinkSetMutationPlan } from \"./linkSet\";\nimport { prepareDocumentLinkBlobRewraps } from \"./linkSetBlobRewraps\";\nimport { seedLinkSetWriterProjection } from \"./linkSetProjectionSeed\";\nimport { completeLinkSetMutationRequest } from \"./rotationBaseline\";\nimport type { SubtreePurgeRoot } from \"./subtreePurgeScope\";\n\nasync function submitLinkSetMutation(input: {\n apiClient: DocumentLinkSetMutationApi;\n documentId: string;\n expectedOrganizationId: string;\n onFailure?: DocumentLinkSetFailureHandler | undefined;\n operation: DocumentLinkSetMutationOperation;\n request: DocumentLinkSetMutationRequest;\n stillCurrent?: (() => boolean) | undefined;\n}): Promise<DocumentLinkSetMutationResponse | null> {\n if (input.stillCurrent?.() === false) return null;\n const { apiClient } = input;\n // Preserve the HTTP failure for the durable move-intent queue.\n const resultFn =\n input.operation === \"link\"\n ? apiClient.linkDocumentResult.bind(apiClient)\n : apiClient.unlinkDocumentResult.bind(apiClient);\n const result = await resultFn(input.documentId, input.request, {\n expectedPaymentRequiredOrganizationId: input.expectedOrganizationId,\n });\n if (result.ok) {\n return result.data;\n }\n input.onFailure?.({\n code: result.code,\n message: result.message,\n status: result.status,\n });\n return null;\n}\n\ninterface LinkSetProjectionFetch<TProjection> {\n failure: DocumentLinkSetMutationFailure | null;\n projection: TProjection | null;\n}\n\n// Cold-cache projection fetches must keep their HTTP status: collapsing a\n// 403 to null would leave an access-denied link/unlink routinely retriable\n// instead of parking its move for the access-restored signal (row 7).\nasync function fetchLinkSetProjection<TProjection>(input: {\n fetchProjectionResult: () => Promise<\n | { readonly data: TProjection; readonly ok: true }\n | DocumentSyncSubmitFailure\n >;\n}): Promise<LinkSetProjectionFetch<TProjection>> {\n const result = await input.fetchProjectionResult();\n if (result.ok) {\n return { failure: null, projection: result.data };\n }\n result.report();\n return {\n failure: {\n code: result.code,\n message: result.message,\n status: result.status,\n },\n projection: null,\n };\n}\n\nfunction fetchLinkSetDocumentProjection(\n apiClient: DocumentLinkSetMutationApi,\n documentId: string,\n): Promise<LinkSetProjectionFetch<DocumentWriterProjectionResponse>> {\n return fetchLinkSetProjection({\n fetchProjectionResult: apiClient.getDocumentWriterProjectionResult.bind(\n apiClient,\n documentId,\n { reportErrors: false },\n ),\n });\n}\n\nfunction fetchLinkSetContainerProjection(\n apiClient: DocumentLinkSetMutationApi,\n containerId: string,\n): Promise<LinkSetProjectionFetch<ContainerWriterProjectionResponse>> {\n return fetchLinkSetProjection({\n fetchProjectionResult: apiClient.getContainerWriterProjectionResult.bind(\n apiClient,\n containerId,\n { reportErrors: false },\n ),\n });\n}\n\nasync function completeRemoteDocumentLinkSet(input: {\n completedPlan: Parameters<\n typeof persistedDocumentLinkSetMutationStateFromResponse\n >[0];\n execSql: ExecSql;\n materializedPlan: Awaited<\n ReturnType<typeof buildMaterializedDocumentLinkSetMutationPlan>\n >;\n operation: DocumentLinkSetMutationOperation;\n response: DocumentLinkSetMutationResponse;\n stillCurrent?: (() => boolean) | undefined;\n targetContainerId: string;\n targetContainerProjection: ContainerWriterProjectionResponse;\n writerProjection: DocumentWriterProjectionResponse;\n apiClient: DocumentLinkSetMutationApi;\n}): Promise<RelinkRemoteDocumentResult | null> {\n const persistedState = persistedDocumentLinkSetMutationStateFromResponse(\n input.completedPlan,\n input.response,\n );\n await acknowledgeDocumentMutation({\n execSql: input.execSql,\n plan: input.completedPlan,\n stillCurrent: input.stillCurrent,\n });\n await seedLinkSetWriterProjection({\n apiClient: input.apiClient,\n execSql: input.execSql,\n operation: input.operation,\n priorProjection: input.writerProjection,\n response: input.response,\n targetContainerId: input.targetContainerId,\n targetContainerProjection: input.targetContainerProjection,\n stillCurrent: input.stillCurrent,\n });\n if (input.stillCurrent?.() === false) return null;\n return {\n contentKey: input.materializedPlan.contentKey,\n contentKeyRotated: input.materializedPlan.contentKeyRotated,\n documentId: input.response.id,\n linkedContainerIds: [\n ...input.materializedPlan.plan.state.linkedContainerIds,\n ],\n persistedState,\n plan: input.completedPlan,\n response: input.response,\n };\n}\n\nexport async function relinkRemoteDocument(input: {\n beforeSubmit?: (() => Promise<boolean>) | undefined;\n apiClient: DocumentLinkSetMutationApi;\n author: DocumentCreateAuthor;\n contentKey?: Uint8Array | undefined;\n documentId: string;\n expectedSubtreeRoot?: SubtreePurgeRoot | undefined;\n eventId?: string | undefined;\n execSql: ExecSql;\n onFailure?: DocumentLinkSetFailureHandler | undefined;\n operation: DocumentLinkSetMutationOperation;\n resolveProjectionUserKey: ProjectionUserKeyResolver;\n rotationSnapshot?: Uint8Array | undefined;\n signedAt?: string | undefined;\n stillCurrent?: (() => boolean) | undefined;\n targetContainerId: string;\n targetSecretKey: Uint8Array;\n warmReferencedPrincipalPolicies?: ReferencedPrincipalPolicyWarmer | undefined;\n}): Promise<RelinkRemoteDocumentResult | null> {\n if (input.operation === \"unlink\" && !input.rotationSnapshot) {\n throw new Error(\n \"Document unlink requires a proven full-history rotation snapshot\",\n );\n }\n const resolveProjectionUserKey = requireProjectionUserKeyResolver(\n input.resolveProjectionUserKey,\n \"Remote document link-set mutation\",\n );\n const [writerFetch, targetContainerFetch] = await Promise.all([\n fetchLinkSetDocumentProjection(input.apiClient, input.documentId),\n fetchLinkSetContainerProjection(input.apiClient, input.targetContainerId),\n ]);\n if (!writerFetch.projection || !targetContainerFetch.projection) {\n for (const failure of orderedProjectionFailures([\n writerFetch.failure,\n targetContainerFetch.failure,\n ])) {\n input.onFailure?.(failure);\n }\n return null;\n }\n const writerProjection = writerFetch.projection;\n const targetContainerProjection = targetContainerFetch.projection;\n if (input.stillCurrent?.() === false) return null;\n\n const signedAt = input.signedAt ?? new Date().toISOString();\n const materializedPlan = await prepareRemoteLinkSetMutation(\n { ...input, resolveProjectionUserKey, signedAt },\n writerProjection,\n targetContainerProjection,\n );\n if (!materializedPlan) return null;\n const request = await completeLinkSetMutationRequest({\n author: input.author,\n materializedPlan,\n operation: input.operation,\n rotationSnapshot: input.rotationSnapshot,\n signedAt,\n });\n const completedPlan = { ...materializedPlan.plan, request };\n if (input.beforeSubmit && !(await input.beforeSubmit())) return null;\n const response = await submitLinkSetMutation({\n apiClient: input.apiClient,\n documentId: completedPlan.documentId,\n expectedOrganizationId: completedPlan.state.organizationId,\n onFailure: input.onFailure,\n operation: input.operation,\n request: completedPlan.request,\n stillCurrent: input.stillCurrent,\n });\n if (!response) {\n return null;\n }\n if (input.stillCurrent?.() === false) return null;\n return completeRemoteDocumentLinkSet({\n apiClient: input.apiClient,\n completedPlan,\n execSql: input.execSql,\n materializedPlan,\n operation: input.operation,\n response,\n stillCurrent: input.stillCurrent,\n targetContainerId: input.targetContainerId,\n targetContainerProjection,\n writerProjection,\n });\n}\n\n// Every projection failure reaches the handler: the queued-move accumulator\n// classifies a vanished container from ANY coded container 404, so a document\n// fetch failure must not hide a container one (or vice versa). A 403 is\n// delivered last, so a single-slot consumer keeps the denial that parks the\n// move (row 7) while the accumulator still sees both.\nfunction orderedProjectionFailures(\n failures: readonly (DocumentLinkSetMutationFailure | null)[],\n): DocumentLinkSetMutationFailure[] {\n const present = failures.filter(\n (failure): failure is DocumentLinkSetMutationFailure => failure !== null,\n );\n return [\n ...present.filter((failure) => failure.status !== 403),\n ...present.filter((failure) => failure.status === 403),\n ];\n}\n\nfunction prepareRemoteLinkSetMutation(\n input: Parameters<typeof relinkRemoteDocument>[0] & {\n resolveProjectionUserKey: ProjectionUserKeyResolver;\n signedAt: string;\n },\n writerProjection: DocumentWriterProjectionResponse,\n targetContainerProjection: ContainerWriterProjectionResponse,\n) {\n return recordDocumentAuthorAccessFailure(\n () =>\n nullOnProjectionVerificationCancellation(() =>\n buildMaterializedDocumentLinkSetMutationPlan({\n author: input.author,\n expectedSubtreeRoot: input.expectedSubtreeRoot,\n prepareBlobRewraps: (targets) =>\n prepareDocumentLinkBlobRewraps({\n ...input,\n targets,\n targetContainerProjection,\n writerProjection,\n }),\n contentKey: input.contentKey,\n eventId: input.eventId,\n execSql: input.execSql,\n operation: input.operation,\n resolveProjectionUserKey: input.resolveProjectionUserKey,\n signedAt: input.signedAt,\n stillCurrent: input.stillCurrent,\n targetContainerProjection,\n targetSecretKey: input.targetSecretKey,\n warmReferencedPrincipalPolicies:\n input.warmReferencedPrincipalPolicies,\n writerProjection,\n }),\n ),\n input.onFailure,\n );\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"orphanBlobReclaimState.js","sourceRoot":"","sources":["orphanBlobReclaimState.ts"],"names":[],"mappings":"AAUA,MAAM,MAAM,GAAG,IAAI,OAAO,EAGvB,CAAC;AAEJ,MAAM,UAAU,sBAAsB,CACpC,WAA0C,EAC1C,OAAgB;IAEhB,IAAI,WAAW,GAAG,MAAM,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IAC1C,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,WAAW,GAAG,IAAI,OAAO,EAAE,CAAC;QAC5B,MAAM,CAAC,GAAG,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;IACvC,CAAC;IACD,IAAI,KAAK,GAAG,WAAW,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IACrC,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,KAAK,GAAG;YACN,mBAAmB,EAAE,IAAI,GAAG,EAAE;YAC9B,KAAK,EAAE,KAAK;YACZ,OAAO,EAAE,SAAS;YAClB,QAAQ,EAAE,0BAA0B,MAAM,CAAC,UAAU,EAAE,EAAE;SAC1D,CAAC;QACF,WAAW,CAAC,GAAG,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IAClC,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC","sourcesContent":["import type { DocumentOrphanBlobPersistence } from \"../../data/persistence/documents/orphanBlobPersistence\";\nimport type { ExecSql } from \"../../data/sqlite/sqlSchema\";\n\nexport interface OrphanBlobReclaimState {\n deferredStorageKeys: Map<string, number>;\n rerun: boolean;\n running: Promise<void> | undefined;\n sweepKey: string;\n}\n\nconst states = new WeakMap<\n DocumentOrphanBlobPersistence,\n WeakMap<ExecSql, OrphanBlobReclaimState>\n>();\n\nexport function orphanBlobReclaimState(\n persistence: DocumentOrphanBlobPersistence,\n execSql: ExecSql,\n): OrphanBlobReclaimState {\n let connections = states.get(persistence);\n if (!connections) {\n connections = new WeakMap();\n states.set(persistence, connections);\n }\n let state = connections.get(execSql);\n if (!state) {\n state = {\n deferredStorageKeys: new Map(),\n rerun: false,\n running: undefined,\n sweepKey: `sweep:document-orphans:${crypto.randomUUID()}`,\n };\n connections.set(execSql, state);\n }\n return state;\n}\n"]}
|