alchemy 2.0.0-beta.77 → 2.0.0-beta.78
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/bin/alchemy.js +1 -1
- package/bin/alchemy.js.map +1 -1
- package/bin/alchemy.ts +1 -1
- package/bin/cli.js +120 -66
- package/bin/exec.js +6723 -6276
- package/bin/exec.js.map +1 -1
- package/bin/exec.ts +1 -1
- package/bin/register-oxc.js +15 -4
- package/lib/AWS/ApiGateway/common.d.ts +1 -1
- package/lib/AWS/ApiGateway/common.d.ts.map +1 -1
- package/lib/AWS/ApiGatewayV2/common.d.ts +1 -1
- package/lib/AWS/ApiGatewayV2/common.d.ts.map +1 -1
- package/lib/AWS/AppSync/common.d.ts +1 -1
- package/lib/AWS/AppSync/common.d.ts.map +1 -1
- package/lib/AWS/Assets.d.ts +1 -1
- package/lib/AWS/Assets.d.ts.map +1 -1
- package/lib/AWS/Bedrock/LanguageModel.d.ts +2 -2
- package/lib/AWS/Bedrock/LanguageModel.d.ts.map +1 -1
- package/lib/AWS/Bedrock/LanguageModel.js +1 -1
- package/lib/AWS/Bedrock/LanguageModel.js.map +1 -1
- package/lib/AWS/Bootstrap.d.ts +2 -2
- package/lib/AWS/Bootstrap.d.ts.map +1 -1
- package/lib/AWS/Budgets/BindingHttp.d.ts +1 -8
- package/lib/AWS/Budgets/BindingHttp.d.ts.map +1 -1
- package/lib/AWS/Budgets/BindingHttp.js +2 -7
- package/lib/AWS/Budgets/BindingHttp.js.map +1 -1
- package/lib/AWS/Budgets/DescribeBudgetActionsForBudgetHttp.d.ts.map +1 -1
- package/lib/AWS/Budgets/DescribeBudgetActionsForBudgetHttp.js +0 -3
- package/lib/AWS/Budgets/DescribeBudgetActionsForBudgetHttp.js.map +1 -1
- package/lib/AWS/CloudFront/KvRoutesUpdate.d.ts.map +1 -1
- package/lib/AWS/CloudFront/KvRoutesUpdate.js +9 -1
- package/lib/AWS/CloudFront/KvRoutesUpdate.js.map +1 -1
- package/lib/AWS/CloudMap/internal.d.ts +2 -2
- package/lib/AWS/CloudMap/internal.d.ts.map +1 -1
- package/lib/AWS/Connection/DbAuthToken.d.ts +2 -1
- package/lib/AWS/Connection/DbAuthToken.d.ts.map +1 -1
- package/lib/AWS/Credentials.d.ts +2 -2
- package/lib/AWS/Credentials.d.ts.map +1 -1
- package/lib/AWS/Credentials.js +1 -1
- package/lib/AWS/Credentials.js.map +1 -1
- package/lib/AWS/DSQL/Connect.d.ts +2 -2
- package/lib/AWS/DSQL/Connect.d.ts.map +1 -1
- package/lib/AWS/DynamoDB/Table.d.ts.map +1 -1
- package/lib/AWS/DynamoDB/Table.js +22 -11
- package/lib/AWS/DynamoDB/Table.js.map +1 -1
- package/lib/AWS/EC2/Instance.d.ts.map +1 -1
- package/lib/AWS/EC2/Instance.js +10 -1
- package/lib/AWS/EC2/Instance.js.map +1 -1
- package/lib/AWS/EC2/SecurityGroup.d.ts +70 -2
- package/lib/AWS/EC2/SecurityGroup.d.ts.map +1 -1
- package/lib/AWS/EC2/SecurityGroup.js +256 -66
- package/lib/AWS/EC2/SecurityGroup.js.map +1 -1
- package/lib/AWS/EC2/SecurityGroupRule.d.ts +43 -9
- package/lib/AWS/EC2/SecurityGroupRule.d.ts.map +1 -1
- package/lib/AWS/EC2/SecurityGroupRule.js +102 -22
- package/lib/AWS/EC2/SecurityGroupRule.js.map +1 -1
- package/lib/AWS/EC2/hosted.d.ts +1 -1
- package/lib/AWS/ECR/Image.d.ts +23 -12
- package/lib/AWS/ECR/Image.d.ts.map +1 -1
- package/lib/AWS/ECR/Image.js +26 -5
- package/lib/AWS/ECR/Image.js.map +1 -1
- package/lib/AWS/ECR/ImageSource.d.ts +1 -1
- package/lib/AWS/ECS/EcsDevWatch.d.ts +1 -1
- package/lib/AWS/ECS/EcsDevWatch.d.ts.map +1 -1
- package/lib/AWS/ECS/FlociServiceProvider.js +2 -2
- package/lib/AWS/ECS/FlociTaskProvider.js +2 -2
- package/lib/AWS/ECS/Service.d.ts.map +1 -1
- package/lib/AWS/ECS/Service.js +7 -7
- package/lib/AWS/ECS/Service.js.map +1 -1
- package/lib/AWS/ECS/Task.d.ts +5 -5
- package/lib/AWS/ECS/Task.d.ts.map +1 -1
- package/lib/AWS/EKS/KubernetesAdapter.js +4 -4
- package/lib/AWS/EKS/internal/podIdentity.d.ts +4 -4
- package/lib/AWS/EKS/internal/podIdentity.d.ts.map +1 -1
- package/lib/AWS/Environment.js +6 -6
- package/lib/AWS/IdentityCenter/common.d.ts +2 -2
- package/lib/AWS/IdentityCenter/common.d.ts.map +1 -1
- package/lib/AWS/Lambda/BindingHttp.d.ts +62 -10
- package/lib/AWS/Lambda/BindingHttp.d.ts.map +1 -1
- package/lib/AWS/Lambda/BindingHttp.js +161 -22
- package/lib/AWS/Lambda/BindingHttp.js.map +1 -1
- package/lib/AWS/Lambda/EventInvokeConfig.d.ts +1 -1
- package/lib/AWS/Lambda/EventInvokeConfig.d.ts.map +1 -1
- package/lib/AWS/Lambda/FlociFunctionProvider.js +2 -2
- package/lib/AWS/Lambda/FlociMicrovmImageProvider.js +2 -2
- package/lib/AWS/Lambda/Function.d.ts.map +1 -1
- package/lib/AWS/Lambda/Function.js +23 -15
- package/lib/AWS/Lambda/Function.js.map +1 -1
- package/lib/AWS/Lambda/FunctionImage.d.ts +1 -1
- package/lib/AWS/Lambda/GetFunctionHttp.d.ts +1 -1
- package/lib/AWS/Lambda/GetFunctionHttp.d.ts.map +1 -1
- package/lib/AWS/Lambda/InvokeFunctionHttp.d.ts +1 -1
- package/lib/AWS/Lambda/InvokeFunctionHttp.d.ts.map +1 -1
- package/lib/AWS/Lambda/InvokeWithResponseStreamHttp.d.ts +1 -1
- package/lib/AWS/Lambda/InvokeWithResponseStreamHttp.d.ts.map +1 -1
- package/lib/AWS/Lambda/MicrovmBinding.d.ts.map +1 -1
- package/lib/AWS/Lambda/MicrovmBinding.js +11 -214
- package/lib/AWS/Lambda/MicrovmBinding.js.map +1 -1
- package/lib/AWS/Lambda/MicrovmBundle.d.ts +1 -1
- package/lib/AWS/Lambda/MicrovmBundle.d.ts.map +1 -1
- package/lib/AWS/Lambda/MicrovmBundle.js +1 -12
- package/lib/AWS/Lambda/MicrovmBundle.js.map +1 -1
- package/lib/AWS/Lambda/MicrovmRuntimeContext.js +1 -1
- package/lib/AWS/Local/DevWatchProvider.d.ts +4 -4
- package/lib/AWS/Local/DevWatchProvider.d.ts.map +1 -1
- package/lib/AWS/Local/DevWatchProvider.js +6 -5
- package/lib/AWS/Local/DevWatchProvider.js.map +1 -1
- package/lib/AWS/Local/Local.d.ts +13 -1
- package/lib/AWS/Local/Local.d.ts.map +1 -1
- package/lib/AWS/Local/Local.js +10 -9
- package/lib/AWS/Local/Local.js.map +1 -1
- package/lib/AWS/Logs/LogGroup.d.ts.map +1 -1
- package/lib/AWS/Logs/LogGroup.js +6 -2
- package/lib/AWS/Logs/LogGroup.js.map +1 -1
- package/lib/AWS/MediaPackageV2/internal.d.ts +1 -1
- package/lib/AWS/MediaPackageV2/internal.d.ts.map +1 -1
- package/lib/AWS/Notifications/internal.d.ts +1 -1
- package/lib/AWS/Notifications/internal.d.ts.map +1 -1
- package/lib/AWS/OAM/internal.d.ts +1 -1
- package/lib/AWS/OAM/internal.d.ts.map +1 -1
- package/lib/AWS/Organizations/common.d.ts.map +1 -1
- package/lib/AWS/Organizations/common.js +4 -1
- package/lib/AWS/Organizations/common.js.map +1 -1
- package/lib/AWS/Personalize/internal.d.ts +1 -1
- package/lib/AWS/Personalize/internal.d.ts.map +1 -1
- package/lib/AWS/RDS/Connect.d.ts +3 -3
- package/lib/AWS/RDS/Connect.d.ts.map +1 -1
- package/lib/AWS/RDS/DBInstance.d.ts +226 -11
- package/lib/AWS/RDS/DBInstance.d.ts.map +1 -1
- package/lib/AWS/RDS/DBInstance.js +692 -36
- package/lib/AWS/RDS/DBInstance.js.map +1 -1
- package/lib/AWS/RDS/DBParameterGroup.d.ts +8 -9
- package/lib/AWS/RDS/DBParameterGroup.d.ts.map +1 -1
- package/lib/AWS/RDS/DBParameterGroup.js +53 -27
- package/lib/AWS/RDS/DBParameterGroup.js.map +1 -1
- package/lib/AWS/Route53/HostedZoneLookup.d.ts +1 -1
- package/lib/AWS/Route53/HostedZoneLookup.d.ts.map +1 -1
- package/lib/AWS/S3/AbortMultipartUploadHttp.d.ts +1 -1
- package/lib/AWS/S3/AbortMultipartUploadHttp.d.ts.map +1 -1
- package/lib/AWS/S3/BindingHttp.d.ts +13 -5
- package/lib/AWS/S3/BindingHttp.d.ts.map +1 -1
- package/lib/AWS/S3/BindingHttp.js +28 -30
- package/lib/AWS/S3/BindingHttp.js.map +1 -1
- package/lib/AWS/S3/Bucket.d.ts +95 -5
- package/lib/AWS/S3/Bucket.d.ts.map +1 -1
- package/lib/AWS/S3/Bucket.js +165 -47
- package/lib/AWS/S3/Bucket.js.map +1 -1
- package/lib/AWS/S3/CompleteMultipartUploadHttp.d.ts +1 -1
- package/lib/AWS/S3/CompleteMultipartUploadHttp.d.ts.map +1 -1
- package/lib/AWS/S3/CopyObjectHttp.d.ts +1 -1
- package/lib/AWS/S3/CopyObjectHttp.d.ts.map +1 -1
- package/lib/AWS/S3/CreateMultipartUploadHttp.d.ts +1 -1
- package/lib/AWS/S3/CreateMultipartUploadHttp.d.ts.map +1 -1
- package/lib/AWS/S3/DeleteObjectHttp.d.ts +1 -1
- package/lib/AWS/S3/DeleteObjectHttp.d.ts.map +1 -1
- package/lib/AWS/S3/DeleteObjectTaggingHttp.d.ts +1 -1
- package/lib/AWS/S3/DeleteObjectTaggingHttp.d.ts.map +1 -1
- package/lib/AWS/S3/DeleteObjectsHttp.d.ts +1 -1
- package/lib/AWS/S3/DeleteObjectsHttp.d.ts.map +1 -1
- package/lib/AWS/S3/GetObjectAttributesHttp.d.ts +1 -1
- package/lib/AWS/S3/GetObjectAttributesHttp.d.ts.map +1 -1
- package/lib/AWS/S3/GetObjectHttp.d.ts +1 -1
- package/lib/AWS/S3/GetObjectHttp.d.ts.map +1 -1
- package/lib/AWS/S3/GetObjectLegalHoldHttp.d.ts +1 -1
- package/lib/AWS/S3/GetObjectLegalHoldHttp.d.ts.map +1 -1
- package/lib/AWS/S3/GetObjectRetentionHttp.d.ts +1 -1
- package/lib/AWS/S3/GetObjectRetentionHttp.d.ts.map +1 -1
- package/lib/AWS/S3/GetObjectTaggingHttp.d.ts +1 -1
- package/lib/AWS/S3/GetObjectTaggingHttp.d.ts.map +1 -1
- package/lib/AWS/S3/HeadObjectHttp.d.ts +1 -1
- package/lib/AWS/S3/HeadObjectHttp.d.ts.map +1 -1
- package/lib/AWS/S3/ListMultipartUploadsHttp.d.ts +1 -1
- package/lib/AWS/S3/ListMultipartUploadsHttp.d.ts.map +1 -1
- package/lib/AWS/S3/ListObjectVersionsHttp.d.ts +1 -1
- package/lib/AWS/S3/ListObjectVersionsHttp.d.ts.map +1 -1
- package/lib/AWS/S3/ListObjectsV2Http.d.ts +1 -1
- package/lib/AWS/S3/ListObjectsV2Http.d.ts.map +1 -1
- package/lib/AWS/S3/ListPartsHttp.d.ts +1 -1
- package/lib/AWS/S3/ListPartsHttp.d.ts.map +1 -1
- package/lib/AWS/S3/PresignGetObject.d.ts +2 -2
- package/lib/AWS/S3/PresignGetObject.d.ts.map +1 -1
- package/lib/AWS/S3/PresignGetObject.js.map +1 -1
- package/lib/AWS/S3/PresignPutObject.d.ts +2 -2
- package/lib/AWS/S3/PresignPutObject.d.ts.map +1 -1
- package/lib/AWS/S3/PresignPutObject.js.map +1 -1
- package/lib/AWS/S3/PutObjectHttp.d.ts +1 -1
- package/lib/AWS/S3/PutObjectHttp.d.ts.map +1 -1
- package/lib/AWS/S3/PutObjectLegalHoldHttp.d.ts +1 -1
- package/lib/AWS/S3/PutObjectLegalHoldHttp.d.ts.map +1 -1
- package/lib/AWS/S3/PutObjectRetentionHttp.d.ts +1 -1
- package/lib/AWS/S3/PutObjectRetentionHttp.d.ts.map +1 -1
- package/lib/AWS/S3/PutObjectTaggingHttp.d.ts +1 -1
- package/lib/AWS/S3/PutObjectTaggingHttp.d.ts.map +1 -1
- package/lib/AWS/S3/RestoreObjectHttp.d.ts +1 -1
- package/lib/AWS/S3/RestoreObjectHttp.d.ts.map +1 -1
- package/lib/AWS/S3/UploadPartCopyHttp.d.ts +1 -1
- package/lib/AWS/S3/UploadPartCopyHttp.d.ts.map +1 -1
- package/lib/AWS/S3/UploadPartHttp.d.ts +1 -1
- package/lib/AWS/S3/UploadPartHttp.d.ts.map +1 -1
- package/lib/AWS/SNS/Subscription.d.ts.map +1 -1
- package/lib/AWS/SNS/Subscription.js +21 -5
- package/lib/AWS/SNS/Subscription.js.map +1 -1
- package/lib/AWS/StateStore/State.d.ts +23 -3
- package/lib/AWS/StateStore/State.d.ts.map +1 -1
- package/lib/AWS/StateStore/State.js +19 -27
- package/lib/AWS/StateStore/State.js.map +1 -1
- package/lib/AWS/Synthetics/Canary.d.ts.map +1 -1
- package/lib/AWS/Synthetics/Canary.js +4 -9
- package/lib/AWS/Synthetics/Canary.js.map +1 -1
- package/lib/Alchemist/Entrypoint.d.ts +22 -0
- package/lib/Alchemist/Entrypoint.d.ts.map +1 -0
- package/lib/Alchemist/Entrypoint.js +27 -0
- package/lib/Alchemist/Entrypoint.js.map +1 -0
- package/lib/Alchemist/Session.d.ts +2 -12
- package/lib/Alchemist/Session.d.ts.map +1 -1
- package/lib/Alchemist/Session.js +5 -14
- package/lib/Alchemist/Session.js.map +1 -1
- package/lib/Alchemist/routes/aws.d.ts +2 -2
- package/lib/Alchemist/routes/aws.d.ts.map +1 -1
- package/lib/Alchemist/routes/cloudflare.d.ts +2 -2
- package/lib/Alchemist/routes/cloudflare.d.ts.map +1 -1
- package/lib/Alchemist/routes/nuke.d.ts +1 -1
- package/lib/Alchemist/routes/nuke.d.ts.map +1 -1
- package/lib/Alchemist/routes/nuke.js +1 -1
- package/lib/Alchemist/routes/state.d.ts.map +1 -1
- package/lib/Alchemist/routes/state.js +6 -2
- package/lib/Alchemist/routes/state.js.map +1 -1
- package/lib/Auth/AuthProvider.js +1 -1
- package/lib/Auth/Demand.js +1 -1
- package/lib/Auth/Env.js +4 -4
- package/lib/Auth/Lock.d.ts.map +1 -1
- package/lib/Auth/Lock.js +4 -3
- package/lib/Auth/Lock.js.map +1 -1
- package/lib/Auth/Profile.js +1 -1
- package/lib/Auth/Resolve.js +1 -1
- package/lib/Cli/LoggingCli.js +1 -1
- package/lib/Cli/commands/aws.d.ts +1 -1
- package/lib/Cli/commands/aws.d.ts.map +1 -1
- package/lib/Cli/commands/aws.js +2 -2
- package/lib/Cli/commands/cloudflare.d.ts +2 -2
- package/lib/Cli/commands/cloudflare.d.ts.map +1 -1
- package/lib/Cli/commands/cloudflare.js +10 -10
- package/lib/Cli/commands/cloudflare.js.map +1 -1
- package/lib/Cli/commands/deploy.js +3 -3
- package/lib/Cli/commands/dev.d.ts +1 -1
- package/lib/Cli/commands/dev.d.ts.map +1 -1
- package/lib/Cli/commands/dev.js +6 -3
- package/lib/Cli/commands/dev.js.map +1 -1
- package/lib/Cli/commands/drift.js +1 -1
- package/lib/Cli/commands/flags.d.ts +2 -0
- package/lib/Cli/commands/flags.d.ts.map +1 -1
- package/lib/Cli/commands/flags.js +14 -12
- package/lib/Cli/commands/flags.js.map +1 -1
- package/lib/Cli/commands/instrument.d.ts +7 -0
- package/lib/Cli/commands/instrument.d.ts.map +1 -1
- package/lib/Cli/commands/instrument.js +9 -1
- package/lib/Cli/commands/instrument.js.map +1 -1
- package/lib/Cli/commands/logs.js +4 -4
- package/lib/Cli/commands/logs.js.map +1 -1
- package/lib/Cli/commands/nuke.d.ts +1 -1
- package/lib/Cli/commands/nuke.d.ts.map +1 -1
- package/lib/Cli/commands/nuke.js +9 -9
- package/lib/Cli/commands/nuke.js.map +1 -1
- package/lib/Cli/commands/profile/commands.js +8 -8
- package/lib/Cli/commands/provider.d.ts +2 -2
- package/lib/Cli/commands/provider.d.ts.map +1 -1
- package/lib/Cli/commands/provider.js +1 -1
- package/lib/Cli/commands/state.js +5 -5
- package/lib/Cli/commands/state.js.map +1 -1
- package/lib/Cli/components/ui/Data.d.ts +1 -1
- package/lib/Cli/components/ui/Data.d.ts.map +1 -1
- package/lib/Cli/components/ui/Data.js +1 -1
- package/lib/Cli/components/ui/Environment.d.ts +1 -1
- package/lib/Cli/components/ui/Environment.d.ts.map +1 -1
- package/lib/Cli/components/ui/Environment.js +3 -3
- package/lib/Cli/components/ui/Environment.js.map +1 -1
- package/lib/Cli/components/ui/Feedback.js +3 -3
- package/lib/Cli/components/ui/Feedback.js.map +1 -1
- package/lib/Cli/components/ui/Interactive.d.ts +1 -1
- package/lib/Cli/components/ui/Interactive.d.ts.map +1 -1
- package/lib/Cli/components/ui/Interactive.js +4 -4
- package/lib/Cli/components/ui/Interactive.js.map +1 -1
- package/lib/Cli/components/ui/Layout.d.ts +2 -2
- package/lib/Cli/components/ui/Layout.d.ts.map +1 -1
- package/lib/Cli/components/ui/Layout.js +3 -3
- package/lib/Cli/components/ui/Layout.js.map +1 -1
- package/lib/Cli/components/ui/Live.d.ts +1 -1
- package/lib/Cli/components/ui/Live.d.ts.map +1 -1
- package/lib/Cli/components/ui/Live.js +2 -2
- package/lib/Cli/components/ui/Live.js.map +1 -1
- package/lib/Cli/components/ui/ProgressBar.d.ts +1 -1
- package/lib/Cli/components/ui/ProgressBar.d.ts.map +1 -1
- package/lib/Cli/components/ui/ProgressBar.js +1 -1
- package/lib/Cli/components/ui/Transcript.js +2 -2
- package/lib/Cli/components/ui/Transcript.js.map +1 -1
- package/lib/Cli/components/ui/Typography.d.ts +1 -1
- package/lib/Cli/components/ui/Typography.d.ts.map +1 -1
- package/lib/Cli/components/ui/Typography.js +2 -2
- package/lib/Cli/components/ui/Typography.js.map +1 -1
- package/lib/Cli/components/view/ApprovePlan.d.ts +1 -2
- package/lib/Cli/components/view/ApprovePlan.d.ts.map +1 -1
- package/lib/Cli/components/view/ApprovePlan.js +3 -3
- package/lib/Cli/components/view/ApprovePlan.js.map +1 -1
- package/lib/Cli/components/view/Help.js +2 -2
- package/lib/Cli/components/view/Help.js.map +1 -1
- package/lib/Cli/components/view/Logo.d.ts +1 -1
- package/lib/Cli/components/view/Logo.d.ts.map +1 -1
- package/lib/Cli/components/view/Logo.js +3 -3
- package/lib/Cli/components/view/Logo.js.map +1 -1
- package/lib/Cli/components/view/Nuke.d.ts +1 -1
- package/lib/Cli/components/view/Nuke.d.ts.map +1 -1
- package/lib/Cli/components/view/Nuke.js +2 -2
- package/lib/Cli/components/view/Nuke.js.map +1 -1
- package/lib/Cli/components/view/PlanDecision.d.ts.map +1 -1
- package/lib/Cli/components/view/PlanDecision.js +3 -3
- package/lib/Cli/components/view/PlanDecision.js.map +1 -1
- package/lib/Cli/components/view/PlanRow.d.ts +1 -1
- package/lib/Cli/components/view/PlanRow.d.ts.map +1 -1
- package/lib/Cli/components/view/PlanRow.js +1 -1
- package/lib/Cli/components/view/PlanView.d.ts +1 -20
- package/lib/Cli/components/view/PlanView.d.ts.map +1 -1
- package/lib/Cli/components/view/PlanView.js +3 -3
- package/lib/Cli/components/view/PlanView.js.map +1 -1
- package/lib/Cli/components/view/Profile.js +2 -2
- package/lib/Cli/components/view/Profile.js.map +1 -1
- package/lib/Cli/components/view/ProfileDashboard.d.ts +2 -2
- package/lib/Cli/components/view/ProfileDashboard.d.ts.map +1 -1
- package/lib/Cli/components/view/ProfileDashboard.js +3 -3
- package/lib/Cli/components/view/ProfileDashboard.js.map +1 -1
- package/lib/Cli/components/view/Prompts.d.ts.map +1 -1
- package/lib/Cli/components/view/Prompts.js +3 -3
- package/lib/Cli/components/view/Prompts.js.map +1 -1
- package/lib/Cli/components/view/Runtime.d.ts.map +1 -1
- package/lib/Cli/components/view/Runtime.js +4 -4
- package/lib/Cli/components/view/Runtime.js.map +1 -1
- package/lib/Cli/components/view/SigilCli.js +2 -2
- package/lib/Cli/components/view/SigilCli.js.map +1 -1
- package/lib/Cli/components/view/StackOutputs.js +2 -2
- package/lib/Cli/components/view/StackOutputs.js.map +1 -1
- package/lib/Cli/components/view/StateExplorer.js +3 -3
- package/lib/Cli/components/view/StateExplorer.js.map +1 -1
- package/lib/Cli/components/view/usePlanPresentation.js +1 -1
- package/lib/Cli/components/view/usePlanPresentation.js.map +1 -1
- package/lib/Cli/components/view/usePlanViewport.js +1 -1
- package/lib/Cli/components/view/usePlanViewport.js.map +1 -1
- package/lib/Cli/exec.d.ts.map +1 -1
- package/lib/Cli/exec.js +3 -2
- package/lib/Cli/exec.js.map +1 -1
- package/lib/Cli/main.d.ts.map +1 -1
- package/lib/Cli/main.js +5 -5
- package/lib/Cli/main.js.map +1 -1
- package/lib/Cloudflare/AI/GatewayProvider.d.ts +1 -1
- package/lib/Cloudflare/AI/GatewayProvider.js +1 -1
- package/lib/Cloudflare/AI/LanguageModel.d.ts +2 -2
- package/lib/Cloudflare/AI/LanguageModel.d.ts.map +1 -1
- package/lib/Cloudflare/AI/LanguageModel.js +1 -1
- package/lib/Cloudflare/AI/ProviderKey.d.ts +3 -3
- package/lib/Cloudflare/AI/ProviderKey.js +3 -3
- package/lib/Cloudflare/AI/SearchToken.d.ts.map +1 -1
- package/lib/Cloudflare/AI/SearchToken.js +3 -6
- package/lib/Cloudflare/AI/SearchToken.js.map +1 -1
- package/lib/Cloudflare/Access.js +1 -1
- package/lib/Cloudflare/Alerting/Webhook.d.ts +1 -1
- package/lib/Cloudflare/Alerting/Webhook.js +1 -1
- package/lib/Cloudflare/Bridge.d.ts +7 -0
- package/lib/Cloudflare/Bridge.d.ts.map +1 -1
- package/lib/Cloudflare/Bridge.js +8 -0
- package/lib/Cloudflare/Bridge.js.map +1 -1
- package/lib/Cloudflare/CloudflareEnvironment.d.ts +2 -8
- package/lib/Cloudflare/CloudflareEnvironment.d.ts.map +1 -1
- package/lib/Cloudflare/CloudflareEnvironment.js +3 -5
- package/lib/Cloudflare/CloudflareEnvironment.js.map +1 -1
- package/lib/Cloudflare/CloudflareEnvironmentService.d.ts +9 -0
- package/lib/Cloudflare/CloudflareEnvironmentService.d.ts.map +1 -0
- package/lib/Cloudflare/CloudflareEnvironmentService.js +5 -0
- package/lib/Cloudflare/CloudflareEnvironmentService.js.map +1 -0
- package/lib/Cloudflare/Containers/ContainerApplication.d.ts +11 -4
- package/lib/Cloudflare/Containers/ContainerApplication.d.ts.map +1 -1
- package/lib/Cloudflare/Containers/ContainerApplication.js +0 -1
- package/lib/Cloudflare/Containers/ContainerApplication.js.map +1 -1
- package/lib/Cloudflare/Containers/ContainerPlatform.d.ts +2 -2
- package/lib/Cloudflare/Containers/ContainerPlatform.d.ts.map +1 -1
- package/lib/Cloudflare/Containers/ContainerPlatform.js +1 -2
- package/lib/Cloudflare/Containers/ContainerPlatform.js.map +1 -1
- package/lib/Cloudflare/Containers/ContainerProvider.d.ts.map +1 -1
- package/lib/Cloudflare/Containers/ContainerProvider.js +122 -65
- package/lib/Cloudflare/Containers/ContainerProvider.js.map +1 -1
- package/lib/Cloudflare/Containers/ContainerPublication.d.ts +4 -0
- package/lib/Cloudflare/Containers/ContainerPublication.d.ts.map +1 -0
- package/lib/Cloudflare/Containers/ContainerPublication.js +8 -0
- package/lib/Cloudflare/Containers/ContainerPublication.js.map +1 -0
- package/lib/Cloudflare/Containers/LocalContainerProvider.d.ts.map +1 -1
- package/lib/Cloudflare/Containers/LocalContainerProvider.js +3 -2
- package/lib/Cloudflare/Containers/LocalContainerProvider.js.map +1 -1
- package/lib/Cloudflare/D1/CloneDatabase.d.ts +1 -1
- package/lib/Cloudflare/D1/CloneDatabase.d.ts.map +1 -1
- package/lib/Cloudflare/D1/Database.js +3 -3
- package/lib/Cloudflare/D1/Database.js.map +1 -1
- package/lib/Cloudflare/D1/ImportDatabase.d.ts +1 -1
- package/lib/Cloudflare/D1/ImportDatabase.d.ts.map +1 -1
- package/lib/Cloudflare/DNS/ReadDnsLocal.d.ts +1 -1
- package/lib/Cloudflare/DNS/ReadDnsLocal.d.ts.map +1 -1
- package/lib/Cloudflare/DNS/ReadWriteDnsLocal.d.ts +1 -1
- package/lib/Cloudflare/DNS/ReadWriteDnsLocal.d.ts.map +1 -1
- package/lib/Cloudflare/DNS/WriteDnsLocal.d.ts +1 -1
- package/lib/Cloudflare/DNS/WriteDnsLocal.d.ts.map +1 -1
- package/lib/Cloudflare/Fetcher.d.ts.map +1 -1
- package/lib/Cloudflare/Fetcher.js +58 -116
- package/lib/Cloudflare/Fetcher.js.map +1 -1
- package/lib/Cloudflare/Flagship/Flag.d.ts +8 -1
- package/lib/Cloudflare/Flagship/Flag.d.ts.map +1 -1
- package/lib/Cloudflare/Flagship/Flag.js.map +1 -1
- package/lib/Cloudflare/HostnameTlsSetting/HostnameTlsSetting.d.ts.map +1 -1
- package/lib/Cloudflare/HostnameTlsSetting/HostnameTlsSetting.js +10 -24
- package/lib/Cloudflare/HostnameTlsSetting/HostnameTlsSetting.js.map +1 -1
- package/lib/Cloudflare/Hyperdrive/Connection.d.ts +1 -1
- package/lib/Cloudflare/Hyperdrive/Connection.d.ts.map +1 -1
- package/lib/Cloudflare/Hyperdrive/Connection.js +10 -7
- package/lib/Cloudflare/Hyperdrive/Connection.js.map +1 -1
- package/lib/Cloudflare/KV/ReadNamespaceHttp.d.ts +1 -1
- package/lib/Cloudflare/KV/ReadNamespaceLocal.d.ts +1 -1
- package/lib/Cloudflare/KV/ReadNamespaceLocal.d.ts.map +1 -1
- package/lib/Cloudflare/KV/ReadWriteNamespaceHttp.d.ts +1 -1
- package/lib/Cloudflare/KV/ReadWriteNamespaceLocal.d.ts +1 -1
- package/lib/Cloudflare/KV/ReadWriteNamespaceLocal.d.ts.map +1 -1
- package/lib/Cloudflare/KV/WriteNamespaceHttp.d.ts +1 -1
- package/lib/Cloudflare/KV/WriteNamespaceLocal.d.ts +1 -1
- package/lib/Cloudflare/KV/WriteNamespaceLocal.d.ts.map +1 -1
- package/lib/Cloudflare/LoadBalancer/LoadBalancer.js +1 -1
- package/lib/Cloudflare/LoadBalancer/LoadBalancer.js.map +1 -1
- package/lib/Cloudflare/LoadBalancer/Monitor.js.map +1 -1
- package/lib/Cloudflare/Local.d.ts +8 -1
- package/lib/Cloudflare/Local.d.ts.map +1 -1
- package/lib/Cloudflare/Local.js +6 -2
- package/lib/Cloudflare/Local.js.map +1 -1
- package/lib/Cloudflare/LocalGateway.d.ts +1 -1
- package/lib/Cloudflare/LocalGateway.d.ts.map +1 -1
- package/lib/Cloudflare/LocalRuntime.d.ts +7 -2
- package/lib/Cloudflare/LocalRuntime.d.ts.map +1 -1
- package/lib/Cloudflare/LocalRuntime.js +8 -2
- package/lib/Cloudflare/LocalRuntime.js.map +1 -1
- package/lib/Cloudflare/Logs.d.ts.map +1 -1
- package/lib/Cloudflare/Logs.js +8 -7
- package/lib/Cloudflare/Logs.js.map +1 -1
- package/lib/Cloudflare/MagicTransit/IpsecTunnel.d.ts +1 -1
- package/lib/Cloudflare/MagicTransit/IpsecTunnel.js +1 -1
- package/lib/Cloudflare/MtlsCertificate/MtlsCertificate.d.ts +1 -1
- package/lib/Cloudflare/MtlsCertificate/MtlsCertificate.js +1 -1
- package/lib/Cloudflare/Organization/Organization.js +1 -1
- package/lib/Cloudflare/Organization/Organization.js.map +1 -1
- package/lib/Cloudflare/OriginTlsClientAuth/Certificate.d.ts +2 -2
- package/lib/Cloudflare/OriginTlsClientAuth/Certificate.js +2 -2
- package/lib/Cloudflare/OriginTlsClientAuth/HostnameAssociation.d.ts +1 -1
- package/lib/Cloudflare/OriginTlsClientAuth/HostnameAssociation.js +1 -1
- package/lib/Cloudflare/OriginTlsClientAuth/HostnameCertificate.d.ts +2 -2
- package/lib/Cloudflare/OriginTlsClientAuth/HostnameCertificate.js +2 -2
- package/lib/Cloudflare/OriginTlsClientAuth/Setting.d.ts +1 -1
- package/lib/Cloudflare/OriginTlsClientAuth/Setting.js +1 -1
- package/lib/Cloudflare/Pipelines/LegacyPipeline.d.ts +2 -2
- package/lib/Cloudflare/Pipelines/LegacyPipeline.js +2 -2
- package/lib/Cloudflare/Pipelines/Sink.d.ts +3 -3
- package/lib/Cloudflare/Pipelines/Sink.js +3 -3
- package/lib/Cloudflare/Providers.d.ts +12 -18
- package/lib/Cloudflare/Providers.d.ts.map +1 -1
- package/lib/Cloudflare/Providers.js +14 -20
- package/lib/Cloudflare/Providers.js.map +1 -1
- package/lib/Cloudflare/Queues/Consumer.js +2 -2
- package/lib/Cloudflare/Queues/Consumer.js.map +1 -1
- package/lib/Cloudflare/Queues/Queue.js +2 -2
- package/lib/Cloudflare/Queues/Queue.js.map +1 -1
- package/lib/Cloudflare/Queues/WriteQueueHttp.d.ts +1 -1
- package/lib/Cloudflare/R2/Bucket.d.ts.map +1 -1
- package/lib/Cloudflare/R2/Bucket.js +15 -2
- package/lib/Cloudflare/R2/Bucket.js.map +1 -1
- package/lib/Cloudflare/R2/BucketBinding.d.ts.map +1 -1
- package/lib/Cloudflare/R2/BucketBinding.js +1 -0
- package/lib/Cloudflare/R2/BucketBinding.js.map +1 -1
- package/lib/Cloudflare/R2/BucketSippy.d.ts +7 -7
- package/lib/Cloudflare/R2/BucketSippy.js +7 -7
- package/lib/Cloudflare/R2/BucketTypes.d.ts +8 -0
- package/lib/Cloudflare/R2/BucketTypes.d.ts.map +1 -1
- package/lib/Cloudflare/R2/BucketTypes.js.map +1 -1
- package/lib/Cloudflare/R2/ReadBucketHttp.d.ts +1 -1
- package/lib/Cloudflare/R2/ReadBucketLocal.d.ts +1 -1
- package/lib/Cloudflare/R2/ReadBucketLocal.d.ts.map +1 -1
- package/lib/Cloudflare/R2/ReadWriteBucketHttp.d.ts +1 -1
- package/lib/Cloudflare/R2/ReadWriteBucketLocal.d.ts +1 -1
- package/lib/Cloudflare/R2/ReadWriteBucketLocal.d.ts.map +1 -1
- package/lib/Cloudflare/R2/WriteBucketBinding.d.ts.map +1 -1
- package/lib/Cloudflare/R2/WriteBucketBinding.js +9 -6
- package/lib/Cloudflare/R2/WriteBucketBinding.js.map +1 -1
- package/lib/Cloudflare/R2/WriteBucketHttp.d.ts +1 -1
- package/lib/Cloudflare/R2/WriteBucketLocal.d.ts +1 -1
- package/lib/Cloudflare/R2/WriteBucketLocal.d.ts.map +1 -1
- package/lib/Cloudflare/R2/index.d.ts +1 -0
- package/lib/Cloudflare/R2/index.d.ts.map +1 -1
- package/lib/Cloudflare/R2/index.js +1 -0
- package/lib/Cloudflare/R2/index.js.map +1 -1
- package/lib/Cloudflare/SecretsStore/Secret.js +3 -3
- package/lib/Cloudflare/SecretsStore/Secret.js.map +1 -1
- package/lib/Cloudflare/Snippets/SnippetRules.d.ts.map +1 -1
- package/lib/Cloudflare/Snippets/SnippetRules.js +5 -3
- package/lib/Cloudflare/Snippets/SnippetRules.js.map +1 -1
- package/lib/Cloudflare/StateStore/Api.d.ts +15 -0
- package/lib/Cloudflare/StateStore/State.d.ts +4 -6
- package/lib/Cloudflare/StateStore/State.d.ts.map +1 -1
- package/lib/Cloudflare/StateStore/State.js +6 -14
- package/lib/Cloudflare/StateStore/State.js.map +1 -1
- package/lib/Cloudflare/Tunnel/ReadTunnelBinding.d.ts +1 -1
- package/lib/Cloudflare/Tunnel/ReadTunnelBinding.d.ts.map +1 -1
- package/lib/Cloudflare/Tunnel/ReadTunnelLocal.d.ts +1 -1
- package/lib/Cloudflare/Tunnel/ReadTunnelLocal.d.ts.map +1 -1
- package/lib/Cloudflare/Tunnel/ReadWriteTunnelBinding.d.ts +1 -1
- package/lib/Cloudflare/Tunnel/ReadWriteTunnelBinding.d.ts.map +1 -1
- package/lib/Cloudflare/Tunnel/ReadWriteTunnelLocal.d.ts +1 -1
- package/lib/Cloudflare/Tunnel/ReadWriteTunnelLocal.d.ts.map +1 -1
- package/lib/Cloudflare/Tunnel/WriteTunnelBinding.d.ts +1 -1
- package/lib/Cloudflare/Tunnel/WriteTunnelBinding.d.ts.map +1 -1
- package/lib/Cloudflare/Tunnel/WriteTunnelLocal.d.ts +1 -1
- package/lib/Cloudflare/Tunnel/WriteTunnelLocal.d.ts.map +1 -1
- package/lib/Cloudflare/Website/Nuxt.d.ts +1 -1
- package/lib/Cloudflare/Website/Nuxt.js +1 -1
- package/lib/Cloudflare/Website/Octane.d.ts +1 -1
- package/lib/Cloudflare/Website/Octane.js +1 -1
- package/lib/Cloudflare/Website/SvelteKit.d.ts +1 -1
- package/lib/Cloudflare/Website/SvelteKit.js +1 -1
- package/lib/Cloudflare/Workers/AIBinding.d.ts +1 -1
- package/lib/Cloudflare/Workers/AIBinding.d.ts.map +1 -1
- package/lib/Cloudflare/Workers/Assets.d.ts +1 -1
- package/lib/Cloudflare/Workers/Assets.d.ts.map +1 -1
- package/lib/Cloudflare/Workers/Assets.js +1 -1
- package/lib/Cloudflare/Workers/Assets.js.map +1 -1
- package/lib/Cloudflare/Workers/BrowserBinding.d.ts +1 -1
- package/lib/Cloudflare/Workers/BrowserBinding.d.ts.map +1 -1
- package/lib/Cloudflare/Workers/CloudflareTracer.js +1 -1
- package/lib/Cloudflare/Workers/CloudflareTracer.js.map +1 -1
- package/lib/Cloudflare/Workers/DurableObject.d.ts +22 -3
- package/lib/Cloudflare/Workers/DurableObject.d.ts.map +1 -1
- package/lib/Cloudflare/Workers/DurableObject.js +4 -4
- package/lib/Cloudflare/Workers/DurableObject.js.map +1 -1
- package/lib/Cloudflare/Workers/DurableObjectBridge.js +1 -1
- package/lib/Cloudflare/Workers/DurableObjectBridge.js.map +1 -1
- package/lib/Cloudflare/Workers/DurableObjectState.js +1 -1
- package/lib/Cloudflare/Workers/DurableObjectState.js.map +1 -1
- package/lib/Cloudflare/Workers/DurableObjectStorage.d.ts.map +1 -1
- package/lib/Cloudflare/Workers/DurableObjectStorage.js +22 -22
- package/lib/Cloudflare/Workers/DurableObjectStorage.js.map +1 -1
- package/lib/Cloudflare/Workers/HttpServer.d.ts +1 -1
- package/lib/Cloudflare/Workers/HttpServer.d.ts.map +1 -1
- package/lib/Cloudflare/Workers/HttpServer.js +1 -1
- package/lib/Cloudflare/Workers/HttpServer.js.map +1 -1
- package/lib/Cloudflare/Workers/InferEnv.d.ts +1 -1
- package/lib/Cloudflare/Workers/InferEnv.d.ts.map +1 -1
- package/lib/Cloudflare/Workers/LocalWorkerProvider.d.ts.map +1 -1
- package/lib/Cloudflare/Workers/LocalWorkerProvider.js +33 -13
- package/lib/Cloudflare/Workers/LocalWorkerProvider.js.map +1 -1
- package/lib/Cloudflare/Workers/RateLimitBinding.d.ts +1 -1
- package/lib/Cloudflare/Workers/RateLimitBinding.d.ts.map +1 -1
- package/lib/Cloudflare/Workers/Rpc.d.ts +9 -1
- package/lib/Cloudflare/Workers/Rpc.d.ts.map +1 -1
- package/lib/Cloudflare/Workers/Rpc.js +4 -3
- package/lib/Cloudflare/Workers/Rpc.js.map +1 -1
- package/lib/Cloudflare/Workers/RpcAsync.js +1 -1
- package/lib/Cloudflare/Workers/RpcAsync.js.map +1 -1
- package/lib/Cloudflare/Workers/SecretKeyBinding.d.ts +1 -1
- package/lib/Cloudflare/Workers/SecretKeyBinding.d.ts.map +1 -1
- package/lib/Cloudflare/Workers/Sources/Prebuilt.d.ts.map +1 -1
- package/lib/Cloudflare/Workers/Sources/Prebuilt.js +3 -2
- package/lib/Cloudflare/Workers/Sources/Prebuilt.js.map +1 -1
- package/lib/Cloudflare/Workers/Sources/Python.d.ts.map +1 -1
- package/lib/Cloudflare/Workers/Sources/Python.js +3 -2
- package/lib/Cloudflare/Workers/Sources/Python.js.map +1 -1
- package/lib/Cloudflare/Workers/Sources/Rolldown.d.ts.map +1 -1
- package/lib/Cloudflare/Workers/Sources/Rolldown.js +24 -9
- package/lib/Cloudflare/Workers/Sources/Rolldown.js.map +1 -1
- package/lib/Cloudflare/Workers/Sources/WorkerModulePlugin.d.ts +23 -0
- package/lib/Cloudflare/Workers/Sources/WorkerModulePlugin.d.ts.map +1 -0
- package/lib/Cloudflare/Workers/Sources/WorkerModulePlugin.js +52 -0
- package/lib/Cloudflare/Workers/Sources/WorkerModulePlugin.js.map +1 -0
- package/lib/Cloudflare/Workers/VersionMetadataBinding.d.ts +1 -1
- package/lib/Cloudflare/Workers/VersionMetadataBinding.d.ts.map +1 -1
- package/lib/Cloudflare/Workers/ViteChild.d.ts.map +1 -1
- package/lib/Cloudflare/Workers/ViteChild.js +2 -1
- package/lib/Cloudflare/Workers/ViteChild.js.map +1 -1
- package/lib/Cloudflare/Workers/ViteChild.shared.d.ts +1 -0
- package/lib/Cloudflare/Workers/ViteChild.shared.d.ts.map +1 -1
- package/lib/Cloudflare/Workers/ViteChild.shared.js.map +1 -1
- package/lib/Cloudflare/Workers/Worker.d.ts +168 -98
- package/lib/Cloudflare/Workers/Worker.d.ts.map +1 -1
- package/lib/Cloudflare/Workers/Worker.js +46 -97
- package/lib/Cloudflare/Workers/Worker.js.map +1 -1
- package/lib/Cloudflare/Workers/WorkerBinding.d.ts +31 -1
- package/lib/Cloudflare/Workers/WorkerBinding.d.ts.map +1 -1
- package/lib/Cloudflare/Workers/WorkerBridge.js +5 -5
- package/lib/Cloudflare/Workers/WorkerBridge.js.map +1 -1
- package/lib/Cloudflare/Workers/WorkerEntrypoint.d.ts +42 -13
- package/lib/Cloudflare/Workers/WorkerEntrypoint.d.ts.map +1 -1
- package/lib/Cloudflare/Workers/WorkerEntrypoint.js +36 -10
- package/lib/Cloudflare/Workers/WorkerEntrypoint.js.map +1 -1
- package/lib/Cloudflare/Workers/WorkerProvider.d.ts +20 -0
- package/lib/Cloudflare/Workers/WorkerProvider.d.ts.map +1 -1
- package/lib/Cloudflare/Workers/WorkerProvider.js +434 -27
- package/lib/Cloudflare/Workers/WorkerProvider.js.map +1 -1
- package/lib/Cloudflare/Workers/WorkerRuntime.d.ts +82 -0
- package/lib/Cloudflare/Workers/WorkerRuntime.d.ts.map +1 -0
- package/lib/Cloudflare/Workers/WorkerRuntime.js +77 -0
- package/lib/Cloudflare/Workers/WorkerRuntime.js.map +1 -0
- package/lib/Cloudflare/Workers/WorkerRuntimeContext.d.ts.map +1 -1
- package/lib/Cloudflare/Workers/WorkerRuntimeContext.js +9 -6
- package/lib/Cloudflare/Workers/WorkerRuntimeContext.js.map +1 -1
- package/lib/Cloudflare/Workflows/Workflow.d.ts +2 -38
- package/lib/Cloudflare/Workflows/Workflow.d.ts.map +1 -1
- package/lib/Cloudflare/Workflows/Workflow.js +2 -21
- package/lib/Cloudflare/Workflows/Workflow.js.map +1 -1
- package/lib/Cloudflare/Workflows/WorkflowBridge.d.ts +2 -1
- package/lib/Cloudflare/Workflows/WorkflowBridge.d.ts.map +1 -1
- package/lib/Cloudflare/Workflows/WorkflowBridge.js +2 -2
- package/lib/Cloudflare/Workflows/WorkflowBridge.js.map +1 -1
- package/lib/Cloudflare/Workflows/WorkflowRuntime.d.ts +42 -0
- package/lib/Cloudflare/Workflows/WorkflowRuntime.d.ts.map +1 -0
- package/lib/Cloudflare/Workflows/WorkflowRuntime.js +20 -0
- package/lib/Cloudflare/Workflows/WorkflowRuntime.js.map +1 -0
- package/lib/Cloudflare/index.d.ts.map +1 -1
- package/lib/Cloudflare/index.js +3 -1
- package/lib/Cloudflare/index.js.map +1 -1
- package/lib/Command/Dev.d.ts.map +1 -1
- package/lib/Command/Dev.js +2 -1
- package/lib/Command/Dev.js.map +1 -1
- package/lib/Command/Local.d.ts +7 -1
- package/lib/Command/Local.d.ts.map +1 -1
- package/lib/Command/Local.js +5 -2
- package/lib/Command/Local.js.map +1 -1
- package/lib/Command/Memo.d.ts.map +1 -1
- package/lib/Command/Memo.js +6 -7
- package/lib/Command/Memo.js.map +1 -1
- package/lib/Docker/Container.d.ts +1 -1
- package/lib/Docker/Container.js +1 -1
- package/lib/Docker/Docker.d.ts +19 -7
- package/lib/Docker/Docker.d.ts.map +1 -1
- package/lib/Docker/Docker.js +132 -54
- package/lib/Docker/Docker.js.map +1 -1
- package/lib/Docker/Image.d.ts +1 -1
- package/lib/Docker/Image.js +1 -1
- package/lib/Docker/Registry.d.ts +1 -1
- package/lib/Docker/RegistryError.d.ts +21 -0
- package/lib/Docker/RegistryError.d.ts.map +1 -0
- package/lib/Docker/RegistryError.js +28 -0
- package/lib/Docker/RegistryError.js.map +1 -0
- package/lib/Docker/RemoteImage.d.ts +1 -1
- package/lib/Docker/RemoteImage.js +1 -1
- package/lib/Docker/ServiceImage.d.ts +1 -1
- package/lib/Docker/index.d.ts +1 -0
- package/lib/Docker/index.d.ts.map +1 -1
- package/lib/Docker/index.js +1 -0
- package/lib/Docker/index.js.map +1 -1
- package/lib/Drizzle/Postgres.d.ts.map +1 -1
- package/lib/Drizzle/Postgres.js +3 -1
- package/lib/Drizzle/Postgres.js.map +1 -1
- package/lib/Fly/BucketBinding.js +5 -5
- package/lib/Fly/GetSecretHttp.js +1 -1
- package/lib/Fly/RedisBinding.js +2 -2
- package/lib/Fly/Secret.d.ts +4 -4
- package/lib/Fly/Secret.js +4 -4
- package/lib/Fly/SecretHttp.js +1 -1
- package/lib/Fly/Service.d.ts +3 -3
- package/lib/Fly/Service.js +3 -3
- package/lib/Fly/Sprite.d.ts +2 -2
- package/lib/Fly/Sprite.js +2 -2
- package/lib/Fly/Website/AssetDeployment.d.ts.map +1 -1
- package/lib/Fly/Website/AssetDeployment.js +1 -1
- package/lib/Fly/Website/AssetDeployment.js.map +1 -1
- package/lib/Fly/replicas.d.ts +5 -5
- package/lib/Fly/replicas.d.ts.map +1 -1
- package/lib/Fly/replicas.js +39 -9
- package/lib/Fly/replicas.js.map +1 -1
- package/lib/Git/Api/GitHub.d.ts +38 -0
- package/lib/Git/Api/GitHub.d.ts.map +1 -0
- package/lib/Git/Api/GitHub.js +38 -0
- package/lib/Git/Api/GitHub.js.map +1 -0
- package/lib/Git/Api/Internal.d.ts +27 -0
- package/lib/Git/Api/Internal.d.ts.map +1 -0
- package/lib/Git/Api/Internal.js +27 -0
- package/lib/Git/Api/Internal.js.map +1 -0
- package/lib/Git/Api/Objects.d.ts +140 -0
- package/lib/Git/Api/Objects.d.ts.map +1 -0
- package/lib/Git/Api/Objects.js +100 -0
- package/lib/Git/Api/Objects.js.map +1 -0
- package/lib/Git/Api/Protocol.d.ts +41 -0
- package/lib/Git/Api/Protocol.d.ts.map +1 -0
- package/lib/Git/Api/Protocol.js +23 -0
- package/lib/Git/Api/Protocol.js.map +1 -0
- package/lib/Git/Api/Pulls.d.ts +157 -0
- package/lib/Git/Api/Pulls.d.ts.map +1 -0
- package/lib/Git/Api/Pulls.js +109 -0
- package/lib/Git/Api/Pulls.js.map +1 -0
- package/lib/Git/Api/Refs.d.ts +95 -0
- package/lib/Git/Api/Refs.d.ts.map +1 -0
- package/lib/Git/Api/Refs.js +70 -0
- package/lib/Git/Api/Refs.js.map +1 -0
- package/lib/Git/Api/Repos.d.ts +168 -0
- package/lib/Git/Api/Repos.d.ts.map +1 -0
- package/lib/Git/Api/Repos.js +123 -0
- package/lib/Git/Api/Repos.js.map +1 -0
- package/lib/Git/Api/Schema.d.ts +511 -0
- package/lib/Git/Api/Schema.d.ts.map +1 -0
- package/lib/Git/Api/Schema.js +443 -0
- package/lib/Git/Api/Schema.js.map +1 -0
- package/lib/Git/Api.d.ts +65 -0
- package/lib/Git/Api.d.ts.map +1 -0
- package/lib/Git/Api.js +54 -0
- package/lib/Git/Api.js.map +1 -0
- package/lib/Git/BlobStore.d.ts +129 -0
- package/lib/Git/BlobStore.d.ts.map +1 -0
- package/lib/Git/BlobStore.js +118 -0
- package/lib/Git/BlobStore.js.map +1 -0
- package/lib/Git/BlobStoreS3.d.ts +13 -0
- package/lib/Git/BlobStoreS3.d.ts.map +1 -0
- package/lib/Git/BlobStoreS3.js +184 -0
- package/lib/Git/BlobStoreS3.js.map +1 -0
- package/lib/Git/Engine.d.ts +127 -0
- package/lib/Git/Engine.d.ts.map +1 -0
- package/lib/Git/Engine.js +290 -0
- package/lib/Git/Engine.js.map +1 -0
- package/lib/Git/GitHubCompat.d.ts +155 -0
- package/lib/Git/GitHubCompat.d.ts.map +1 -0
- package/lib/Git/GitHubCompat.js +444 -0
- package/lib/Git/GitHubCompat.js.map +1 -0
- package/lib/Git/Hasher/Hasher.d.ts +129 -0
- package/lib/Git/Hasher/Hasher.d.ts.map +1 -0
- package/lib/Git/Hasher/Hasher.js +170 -0
- package/lib/Git/Hasher/Hasher.js.map +1 -0
- package/lib/Git/Hasher/Lambda.d.ts +18 -0
- package/lib/Git/Hasher/Lambda.d.ts.map +1 -0
- package/lib/Git/Hasher/Lambda.js +81 -0
- package/lib/Git/Hasher/Lambda.js.map +1 -0
- package/lib/Git/Hasher/LambdaEvent.d.ts +45 -0
- package/lib/Git/Hasher/LambdaEvent.d.ts.map +1 -0
- package/lib/Git/Hasher/LambdaEvent.js +99 -0
- package/lib/Git/Hasher/LambdaEvent.js.map +1 -0
- package/lib/Git/Hasher/LambdaFunction.d.ts +7 -0
- package/lib/Git/Hasher/LambdaFunction.d.ts.map +1 -0
- package/lib/Git/Hasher/LambdaFunction.js +41 -0
- package/lib/Git/Hasher/LambdaFunction.js.map +1 -0
- package/lib/Git/Hasher/Protocol.d.ts +46 -0
- package/lib/Git/Hasher/Protocol.d.ts.map +1 -0
- package/lib/Git/Hasher/Protocol.js +235 -0
- package/lib/Git/Hasher/Protocol.js.map +1 -0
- package/lib/Git/Hasher/WorkerLoader.d.ts +17 -0
- package/lib/Git/Hasher/WorkerLoader.d.ts.map +1 -0
- package/lib/Git/Hasher/WorkerLoader.js +90 -0
- package/lib/Git/Hasher/WorkerLoader.js.map +1 -0
- package/lib/Git/Hasher/WorkerLoaderModule.d.ts +5 -0
- package/lib/Git/Hasher/WorkerLoaderModule.d.ts.map +1 -0
- package/lib/Git/Hasher/WorkerLoaderModule.js +47 -0
- package/lib/Git/Hasher/WorkerLoaderModule.js.map +1 -0
- package/lib/Git/Hasher/index.d.ts +16 -0
- package/lib/Git/Hasher/index.d.ts.map +1 -0
- package/lib/Git/Hasher/index.js +16 -0
- package/lib/Git/Hasher/index.js.map +1 -0
- package/lib/Git/Http/ReceivePack.d.ts +38 -0
- package/lib/Git/Http/ReceivePack.d.ts.map +1 -0
- package/lib/Git/Http/ReceivePack.js +94 -0
- package/lib/Git/Http/ReceivePack.js.map +1 -0
- package/lib/Git/Http.d.ts +5 -0
- package/lib/Git/Http.d.ts.map +1 -0
- package/lib/Git/Http.js +5 -0
- package/lib/Git/Http.js.map +1 -0
- package/lib/Git/Jobs/Bundle.d.ts +139 -0
- package/lib/Git/Jobs/Bundle.d.ts.map +1 -0
- package/lib/Git/Jobs/Bundle.js +160 -0
- package/lib/Git/Jobs/Bundle.js.map +1 -0
- package/lib/Git/Jobs/Compact.d.ts +145 -0
- package/lib/Git/Jobs/Compact.d.ts.map +1 -0
- package/lib/Git/Jobs/Compact.js +331 -0
- package/lib/Git/Jobs/Compact.js.map +1 -0
- package/lib/Git/Jobs/Fork.d.ts +116 -0
- package/lib/Git/Jobs/Fork.d.ts.map +1 -0
- package/lib/Git/Jobs/Fork.js +173 -0
- package/lib/Git/Jobs/Fork.js.map +1 -0
- package/lib/Git/Jobs/Import.d.ts +144 -0
- package/lib/Git/Jobs/Import.d.ts.map +1 -0
- package/lib/Git/Jobs/Import.js +291 -0
- package/lib/Git/Jobs/Import.js.map +1 -0
- package/lib/Git/Jobs/Purge.d.ts +62 -0
- package/lib/Git/Jobs/Purge.d.ts.map +1 -0
- package/lib/Git/Jobs/Purge.js +55 -0
- package/lib/Git/Jobs/Purge.js.map +1 -0
- package/lib/Git/Operations.d.ts +136 -0
- package/lib/Git/Operations.d.ts.map +1 -0
- package/lib/Git/Operations.js +684 -0
- package/lib/Git/Operations.js.map +1 -0
- package/lib/Git/Protocol/Advertise.d.ts +50 -0
- package/lib/Git/Protocol/Advertise.d.ts.map +1 -0
- package/lib/Git/Protocol/Advertise.js +116 -0
- package/lib/Git/Protocol/Advertise.js.map +1 -0
- package/lib/Git/Protocol/Delta.d.ts +60 -0
- package/lib/Git/Protocol/Delta.d.ts.map +1 -0
- package/lib/Git/Protocol/Delta.js +147 -0
- package/lib/Git/Protocol/Delta.js.map +1 -0
- package/lib/Git/Protocol/GzipBody.d.ts +65 -0
- package/lib/Git/Protocol/GzipBody.d.ts.map +1 -0
- package/lib/Git/Protocol/GzipBody.js +108 -0
- package/lib/Git/Protocol/GzipBody.js.map +1 -0
- package/lib/Git/Protocol/ObjectCodec.d.ts +346 -0
- package/lib/Git/Protocol/ObjectCodec.d.ts.map +1 -0
- package/lib/Git/Protocol/ObjectCodec.js +685 -0
- package/lib/Git/Protocol/ObjectCodec.js.map +1 -0
- package/lib/Git/Protocol/PackParser.d.ts +231 -0
- package/lib/Git/Protocol/PackParser.d.ts.map +1 -0
- package/lib/Git/Protocol/PackParser.js +636 -0
- package/lib/Git/Protocol/PackParser.js.map +1 -0
- package/lib/Git/Protocol/PackWriter.d.ts +50 -0
- package/lib/Git/Protocol/PackWriter.d.ts.map +1 -0
- package/lib/Git/Protocol/PackWriter.js +82 -0
- package/lib/Git/Protocol/PackWriter.js.map +1 -0
- package/lib/Git/Protocol/PartialScan.d.ts +183 -0
- package/lib/Git/Protocol/PartialScan.d.ts.map +1 -0
- package/lib/Git/Protocol/PartialScan.js +513 -0
- package/lib/Git/Protocol/PartialScan.js.map +1 -0
- package/lib/Git/Protocol/Pkt.d.ts +107 -0
- package/lib/Git/Protocol/Pkt.d.ts.map +1 -0
- package/lib/Git/Protocol/Pkt.js +227 -0
- package/lib/Git/Protocol/Pkt.js.map +1 -0
- package/lib/Git/Protocol/ReceivePack.d.ts +190 -0
- package/lib/Git/Protocol/ReceivePack.d.ts.map +1 -0
- package/lib/Git/Protocol/ReceivePack.js +250 -0
- package/lib/Git/Protocol/ReceivePack.js.map +1 -0
- package/lib/Git/Protocol/Sideband.d.ts +97 -0
- package/lib/Git/Protocol/Sideband.d.ts.map +1 -0
- package/lib/Git/Protocol/Sideband.js +214 -0
- package/lib/Git/Protocol/Sideband.js.map +1 -0
- package/lib/Git/Protocol/Store.d.ts +160 -0
- package/lib/Git/Protocol/Store.d.ts.map +1 -0
- package/lib/Git/Protocol/Store.js +11 -0
- package/lib/Git/Protocol/Store.js.map +1 -0
- package/lib/Git/Protocol/TreeDiff.d.ts +114 -0
- package/lib/Git/Protocol/TreeDiff.d.ts.map +1 -0
- package/lib/Git/Protocol/TreeDiff.js +347 -0
- package/lib/Git/Protocol/TreeDiff.js.map +1 -0
- package/lib/Git/Protocol/UploadPack.d.ts +103 -0
- package/lib/Git/Protocol/UploadPack.d.ts.map +1 -0
- package/lib/Git/Protocol/UploadPack.js +269 -0
- package/lib/Git/Protocol/UploadPack.js.map +1 -0
- package/lib/Git/Protocol/Zlib.d.ts +75 -0
- package/lib/Git/Protocol/Zlib.d.ts.map +1 -0
- package/lib/Git/Protocol/Zlib.js +256 -0
- package/lib/Git/Protocol/Zlib.js.map +1 -0
- package/lib/Git/Push.d.ts +47 -0
- package/lib/Git/Push.d.ts.map +1 -0
- package/lib/Git/Push.js +12 -0
- package/lib/Git/Push.js.map +1 -0
- package/lib/Git/PushInput.d.ts +14 -0
- package/lib/Git/PushInput.d.ts.map +1 -0
- package/lib/Git/PushInput.js +45 -0
- package/lib/Git/PushInput.js.map +1 -0
- package/lib/Git/PushWire.d.ts +17 -0
- package/lib/Git/PushWire.d.ts.map +1 -0
- package/lib/Git/PushWire.js +49 -0
- package/lib/Git/PushWire.js.map +1 -0
- package/lib/Git/RegistryD1.d.ts +10 -0
- package/lib/Git/RegistryD1.d.ts.map +1 -0
- package/lib/Git/RegistryD1.js +188 -0
- package/lib/Git/RegistryD1.js.map +1 -0
- package/lib/Git/RegistryObject.d.ts +210 -0
- package/lib/Git/RegistryObject.d.ts.map +1 -0
- package/lib/Git/RegistryObject.js +287 -0
- package/lib/Git/RegistryObject.js.map +1 -0
- package/lib/Git/RepoObject.d.ts +804 -0
- package/lib/Git/RepoObject.d.ts.map +1 -0
- package/lib/Git/RepoObject.js +3839 -0
- package/lib/Git/RepoObject.js.map +1 -0
- package/lib/Git/Server.d.ts +215 -0
- package/lib/Git/Server.d.ts.map +1 -0
- package/lib/Git/Server.js +620 -0
- package/lib/Git/Server.js.map +1 -0
- package/lib/Git/Store/Closure.d.ts +85 -0
- package/lib/Git/Store/Closure.d.ts.map +1 -0
- package/lib/Git/Store/Closure.js +374 -0
- package/lib/Git/Store/Closure.js.map +1 -0
- package/lib/Git/Store/HeadSnapshot.d.ts +38 -0
- package/lib/Git/Store/HeadSnapshot.d.ts.map +1 -0
- package/lib/Git/Store/HeadSnapshot.js +12 -0
- package/lib/Git/Store/HeadSnapshot.js.map +1 -0
- package/lib/Git/Store/IncomingBody.d.ts +37 -0
- package/lib/Git/Store/IncomingBody.d.ts.map +1 -0
- package/lib/Git/Store/IncomingBody.js +61 -0
- package/lib/Git/Store/IncomingBody.js.map +1 -0
- package/lib/Git/Store/Keys.d.ts +105 -0
- package/lib/Git/Store/Keys.d.ts.map +1 -0
- package/lib/Git/Store/Keys.js +107 -0
- package/lib/Git/Store/Keys.js.map +1 -0
- package/lib/Git/Store/ObjectStore.d.ts +210 -0
- package/lib/Git/Store/ObjectStore.d.ts.map +1 -0
- package/lib/Git/Store/ObjectStore.js +598 -0
- package/lib/Git/Store/ObjectStore.js.map +1 -0
- package/lib/Git/Store/PackSource.d.ts +23 -0
- package/lib/Git/Store/PackSource.d.ts.map +1 -0
- package/lib/Git/Store/PackSource.js +129 -0
- package/lib/Git/Store/PackSource.js.map +1 -0
- package/lib/Git/Store/Sql.d.ts +213 -0
- package/lib/Git/Store/Sql.d.ts.map +1 -0
- package/lib/Git/Store/Sql.js +244 -0
- package/lib/Git/Store/Sql.js.map +1 -0
- package/lib/Git/Store/StreamingSource.d.ts +66 -0
- package/lib/Git/Store/StreamingSource.d.ts.map +1 -0
- package/lib/Git/Store/StreamingSource.js +274 -0
- package/lib/Git/Store/StreamingSource.js.map +1 -0
- package/lib/Git/index.d.ts +39 -0
- package/lib/Git/index.d.ts.map +1 -0
- package/lib/Git/index.js +38 -0
- package/lib/Git/index.js.map +1 -0
- package/lib/GitHub/BranchProtection.d.ts +309 -0
- package/lib/GitHub/BranchProtection.d.ts.map +1 -0
- package/lib/GitHub/BranchProtection.js +334 -0
- package/lib/GitHub/BranchProtection.js.map +1 -0
- package/lib/GitHub/Collaborator.d.ts +112 -0
- package/lib/GitHub/Collaborator.d.ts.map +1 -0
- package/lib/GitHub/Collaborator.js +164 -0
- package/lib/GitHub/Collaborator.js.map +1 -0
- package/lib/GitHub/Env.js +7 -7
- package/lib/GitHub/Issue.d.ts +168 -0
- package/lib/GitHub/Issue.d.ts.map +1 -0
- package/lib/GitHub/Issue.js +229 -0
- package/lib/GitHub/Issue.js.map +1 -0
- package/lib/GitHub/Label.d.ts +194 -0
- package/lib/GitHub/Label.d.ts.map +1 -0
- package/lib/GitHub/Label.js +260 -0
- package/lib/GitHub/Label.js.map +1 -0
- package/lib/GitHub/Milestone.d.ts +203 -0
- package/lib/GitHub/Milestone.d.ts.map +1 -0
- package/lib/GitHub/Milestone.js +261 -0
- package/lib/GitHub/Milestone.js.map +1 -0
- package/lib/GitHub/Providers.d.ts +1 -2
- package/lib/GitHub/Providers.d.ts.map +1 -1
- package/lib/GitHub/Providers.js +22 -3
- package/lib/GitHub/Providers.js.map +1 -1
- package/lib/GitHub/PullRequest.d.ts +220 -0
- package/lib/GitHub/PullRequest.d.ts.map +1 -0
- package/lib/GitHub/PullRequest.js +323 -0
- package/lib/GitHub/PullRequest.js.map +1 -0
- package/lib/GitHub/Release.d.ts +256 -0
- package/lib/GitHub/Release.d.ts.map +1 -0
- package/lib/GitHub/Release.js +315 -0
- package/lib/GitHub/Release.js.map +1 -0
- package/lib/GitHub/Ruleset.d.ts +277 -0
- package/lib/GitHub/Ruleset.d.ts.map +1 -0
- package/lib/GitHub/Ruleset.js +284 -0
- package/lib/GitHub/Ruleset.js.map +1 -0
- package/lib/GitHub/TeamAccess.d.ts +130 -0
- package/lib/GitHub/TeamAccess.d.ts.map +1 -0
- package/lib/GitHub/TeamAccess.js +176 -0
- package/lib/GitHub/TeamAccess.js.map +1 -0
- package/lib/GitHub/WikiPage.d.ts +252 -0
- package/lib/GitHub/WikiPage.d.ts.map +1 -0
- package/lib/GitHub/WikiPage.js +360 -0
- package/lib/GitHub/WikiPage.js.map +1 -0
- package/lib/GitHub/index.d.ts +10 -0
- package/lib/GitHub/index.d.ts.map +1 -1
- package/lib/GitHub/index.js +10 -0
- package/lib/GitHub/index.js.map +1 -1
- package/lib/Hetzner/Server.d.ts.map +1 -1
- package/lib/Hetzner/Server.js +29 -6
- package/lib/Hetzner/Server.js.map +1 -1
- package/lib/Hetzner/hosted.d.ts +1 -1
- package/lib/Http/Platform.d.ts +18 -0
- package/lib/Http/Platform.d.ts.map +1 -0
- package/lib/Http/Platform.js +35 -0
- package/lib/Http/Platform.js.map +1 -0
- package/lib/Http/index.d.ts +6 -0
- package/lib/Http/index.d.ts.map +1 -0
- package/lib/Http/index.js +6 -0
- package/lib/Http/index.js.map +1 -0
- package/lib/Http.d.ts +7 -1
- package/lib/Http.d.ts.map +1 -1
- package/lib/Http.js +2 -4
- package/lib/Http.js.map +1 -1
- package/lib/Kubernetes/internal/helm.js +1 -1
- package/lib/Kubernetes/internal/kubeconfig.js +1 -1
- package/lib/Kubernetes/internal/workload.js +4 -4
- package/lib/Local/LocalProvider.d.ts +3 -2
- package/lib/Local/LocalProvider.d.ts.map +1 -1
- package/lib/Local/LocalProvider.js +3 -2
- package/lib/Local/LocalProvider.js.map +1 -1
- package/lib/Local/ProviderLayer.d.ts +12 -9
- package/lib/Local/ProviderLayer.d.ts.map +1 -1
- package/lib/Local/ProviderLayer.js +25 -15
- package/lib/Local/ProviderLayer.js.map +1 -1
- package/lib/Local/RpcProvider.d.ts +2 -2
- package/lib/Local/RpcProvider.d.ts.map +1 -1
- package/lib/Local/RpcProvider.js +2 -2
- package/lib/Local/RpcProvider.js.map +1 -1
- package/lib/Local/RpcProviderProxy.d.ts +13 -1
- package/lib/Local/RpcProviderProxy.d.ts.map +1 -1
- package/lib/Local/RpcProviderProxy.js +16 -17
- package/lib/Local/RpcProviderProxy.js.map +1 -1
- package/lib/Local/RpcServer.d.ts +31 -10
- package/lib/Local/RpcServer.d.ts.map +1 -1
- package/lib/Local/RpcServer.js +31 -21
- package/lib/Local/RpcServer.js.map +1 -1
- package/lib/Local/RpcServerEnvironment.js +1 -1
- package/lib/Local/RpcSpawner.js +1 -1
- package/lib/Local/Sidecar.d.ts +2 -0
- package/lib/Local/Sidecar.d.ts.map +1 -0
- package/lib/Local/Sidecar.js +30 -0
- package/lib/Local/Sidecar.js.map +1 -0
- package/lib/Nuke.d.ts.map +1 -1
- package/lib/Nuke.js +25 -23
- package/lib/Nuke.js.map +1 -1
- package/lib/Output.js +1 -1
- package/lib/Phase.js +2 -2
- package/lib/Plan.d.ts.map +1 -1
- package/lib/Plan.js +7 -4
- package/lib/Plan.js.map +1 -1
- package/lib/Planetscale/Credentials.js +1 -1
- package/lib/Prisma/App.d.ts.map +1 -1
- package/lib/Prisma/App.js +81 -43
- package/lib/Prisma/App.js.map +1 -1
- package/lib/Prisma/Branch.d.ts.map +1 -1
- package/lib/Prisma/Branch.js +81 -36
- package/lib/Prisma/Branch.js.map +1 -1
- package/lib/Prisma/Bucket.d.ts.map +1 -1
- package/lib/Prisma/Bucket.js +41 -21
- package/lib/Prisma/Bucket.js.map +1 -1
- package/lib/Prisma/BucketAccessKey.d.ts.map +1 -1
- package/lib/Prisma/BucketAccessKey.js +46 -19
- package/lib/Prisma/BucketAccessKey.js.map +1 -1
- package/lib/Prisma/Client.d.ts +2 -1
- package/lib/Prisma/Client.d.ts.map +1 -1
- package/lib/Prisma/Client.js +5 -5
- package/lib/Prisma/Client.js.map +1 -1
- package/lib/Prisma/Compute.d.ts +82 -10
- package/lib/Prisma/Compute.d.ts.map +1 -1
- package/lib/Prisma/Compute.js +233 -116
- package/lib/Prisma/Compute.js.map +1 -1
- package/lib/Prisma/ComputeArchive.d.ts +9 -0
- package/lib/Prisma/ComputeArchive.d.ts.map +1 -1
- package/lib/Prisma/ComputeArchive.js +14 -4
- package/lib/Prisma/ComputeArchive.js.map +1 -1
- package/lib/Prisma/ComputeBuild.d.ts +67 -2
- package/lib/Prisma/ComputeBuild.d.ts.map +1 -1
- package/lib/Prisma/ComputeBuild.js +147 -1
- package/lib/Prisma/ComputeBuild.js.map +1 -1
- package/lib/Prisma/ComputeLifecycle.d.ts +51 -8
- package/lib/Prisma/ComputeLifecycle.d.ts.map +1 -1
- package/lib/Prisma/ComputeLifecycle.js +82 -40
- package/lib/Prisma/ComputeLifecycle.js.map +1 -1
- package/lib/Prisma/Connection.d.ts.map +1 -1
- package/lib/Prisma/Connection.js +72 -30
- package/lib/Prisma/Connection.js.map +1 -1
- package/lib/Prisma/Credentials.d.ts +22 -0
- package/lib/Prisma/Credentials.d.ts.map +1 -0
- package/lib/Prisma/Credentials.js +43 -0
- package/lib/Prisma/Credentials.js.map +1 -0
- package/lib/Prisma/Database.d.ts +9 -4
- package/lib/Prisma/Database.d.ts.map +1 -1
- package/lib/Prisma/Database.js +102 -66
- package/lib/Prisma/Database.js.map +1 -1
- package/lib/Prisma/Deployment.d.ts.map +1 -1
- package/lib/Prisma/Deployment.js +55 -26
- package/lib/Prisma/Deployment.js.map +1 -1
- package/lib/Prisma/EnvironmentVariable.d.ts.map +1 -1
- package/lib/Prisma/EnvironmentVariable.js +50 -26
- package/lib/Prisma/EnvironmentVariable.js.map +1 -1
- package/lib/Prisma/Internal/AppPromotion.d.ts +5 -4
- package/lib/Prisma/Internal/AppPromotion.d.ts.map +1 -1
- package/lib/Prisma/Internal/AppPromotion.js +16 -15
- package/lib/Prisma/Internal/AppPromotion.js.map +1 -1
- package/lib/Prisma/Internal/DatabaseSecrets.d.ts +5 -5
- package/lib/Prisma/Internal/DatabaseSecrets.d.ts.map +1 -1
- package/lib/Prisma/Internal/DatabaseSecrets.js +10 -5
- package/lib/Prisma/Internal/DatabaseSecrets.js.map +1 -1
- package/lib/Prisma/Internal/DeploymentActions.d.ts +3 -3
- package/lib/Prisma/Internal/DeploymentActions.d.ts.map +1 -1
- package/lib/Prisma/Internal/DeploymentActions.js +7 -11
- package/lib/Prisma/Internal/DeploymentActions.js.map +1 -1
- package/lib/Prisma/Internal/DeploymentIdentity.d.ts +2 -3
- package/lib/Prisma/Internal/DeploymentIdentity.d.ts.map +1 -1
- package/lib/Prisma/Internal/DeploymentIdentity.js +23 -2
- package/lib/Prisma/Internal/DeploymentIdentity.js.map +1 -1
- package/lib/Prisma/Internal/DeploymentObserve.d.ts +2 -2
- package/lib/Prisma/Internal/DeploymentObserve.d.ts.map +1 -1
- package/lib/Prisma/Internal/DeploymentObserve.js +3 -1
- package/lib/Prisma/Internal/DeploymentObserve.js.map +1 -1
- package/lib/Prisma/Internal/LogsClient.d.ts +8 -0
- package/lib/Prisma/Internal/LogsClient.d.ts.map +1 -0
- package/lib/Prisma/Internal/LogsClient.js +120 -0
- package/lib/Prisma/Internal/LogsClient.js.map +1 -0
- package/lib/Prisma/Internal/Observed.d.ts +164 -0
- package/lib/Prisma/Internal/Observed.d.ts.map +1 -0
- package/lib/Prisma/Internal/Observed.js +36 -0
- package/lib/Prisma/Internal/Observed.js.map +1 -0
- package/lib/Prisma/Internal/Pagination.d.ts +18 -0
- package/lib/Prisma/Internal/Pagination.d.ts.map +1 -0
- package/lib/Prisma/Internal/Pagination.js +13 -0
- package/lib/Prisma/Internal/Pagination.js.map +1 -0
- package/lib/Prisma/Operations.d.ts +2 -2
- package/lib/Prisma/Operations.d.ts.map +1 -1
- package/lib/Prisma/Operations.js +3 -2
- package/lib/Prisma/Operations.js.map +1 -1
- package/lib/Prisma/PrismaEnvironment.js +1 -1
- package/lib/Prisma/PrismaLogs.d.ts +2 -2
- package/lib/Prisma/PrismaLogs.d.ts.map +1 -1
- package/lib/Prisma/PrismaLogs.js +13 -4
- package/lib/Prisma/PrismaLogs.js.map +1 -1
- package/lib/Prisma/Project.d.ts +1 -2
- package/lib/Prisma/Project.d.ts.map +1 -1
- package/lib/Prisma/Project.js +84 -52
- package/lib/Prisma/Project.js.map +1 -1
- package/lib/Prisma/Providers.d.ts +18 -2
- package/lib/Prisma/Providers.d.ts.map +1 -1
- package/lib/Prisma/Providers.js +24 -5
- package/lib/Prisma/Providers.js.map +1 -1
- package/lib/Prisma/SourceRepository.d.ts.map +1 -1
- package/lib/Prisma/SourceRepository.js +137 -45
- package/lib/Prisma/SourceRepository.js.map +1 -1
- package/lib/Provider.d.ts +6 -2
- package/lib/Provider.d.ts.map +1 -1
- package/lib/Provider.js +12 -8
- package/lib/Provider.js.map +1 -1
- package/lib/Railway/AuditLog.d.ts +46 -5
- package/lib/Railway/AuditLog.d.ts.map +1 -1
- package/lib/Railway/AuditLog.js +14 -4
- package/lib/Railway/AuditLog.js.map +1 -1
- package/lib/Railway/AuthProvider.js.map +1 -1
- package/lib/Railway/Bucket.d.ts +1 -1
- package/lib/Railway/Bucket.d.ts.map +1 -1
- package/lib/Railway/Bucket.js +39 -19
- package/lib/Railway/Bucket.js.map +1 -1
- package/lib/Railway/BucketBinding.js +5 -5
- package/lib/Railway/Catalog.d.ts +42 -4
- package/lib/Railway/Catalog.d.ts.map +1 -1
- package/lib/Railway/Catalog.js +6 -1
- package/lib/Railway/Catalog.js.map +1 -1
- package/lib/Railway/CloudAgent.d.ts +68 -4
- package/lib/Railway/CloudAgent.d.ts.map +1 -1
- package/lib/Railway/CloudAgent.js +24 -20
- package/lib/Railway/CloudAgent.js.map +1 -1
- package/lib/Railway/CustomDomain.d.ts +1 -1
- package/lib/Railway/CustomDomain.d.ts.map +1 -1
- package/lib/Railway/CustomDomain.js +58 -32
- package/lib/Railway/CustomDomain.js.map +1 -1
- package/lib/Railway/Environment.d.ts +20 -2
- package/lib/Railway/Environment.d.ts.map +1 -1
- package/lib/Railway/Environment.js +7 -2
- package/lib/Railway/Environment.js.map +1 -1
- package/lib/Railway/Function.d.ts +1 -1
- package/lib/Railway/Function.d.ts.map +1 -1
- package/lib/Railway/Function.js +73 -55
- package/lib/Railway/Function.js.map +1 -1
- package/lib/Railway/GraphQL.d.ts +1230 -0
- package/lib/Railway/GraphQL.d.ts.map +1 -0
- package/lib/Railway/GraphQL.js +132 -0
- package/lib/Railway/GraphQL.js.map +1 -0
- package/lib/Railway/Group.d.ts +1 -1
- package/lib/Railway/Group.d.ts.map +1 -1
- package/lib/Railway/Group.js +101 -30
- package/lib/Railway/Group.js.map +1 -1
- package/lib/Railway/LoginSession.d.ts +10 -2
- package/lib/Railway/LoginSession.d.ts.map +1 -1
- package/lib/Railway/LoginSession.js +5 -4
- package/lib/Railway/LoginSession.js.map +1 -1
- package/lib/Railway/Mongo.d.ts +1 -1
- package/lib/Railway/Mongo.d.ts.map +1 -1
- package/lib/Railway/Mongo.js +107 -93
- package/lib/Railway/Mongo.js.map +1 -1
- package/lib/Railway/MountVolume.d.ts.map +1 -1
- package/lib/Railway/MountVolume.js +5 -4
- package/lib/Railway/MountVolume.js.map +1 -1
- package/lib/Railway/MySQL.d.ts +1 -1
- package/lib/Railway/MySQL.d.ts.map +1 -1
- package/lib/Railway/MySQL.js +107 -93
- package/lib/Railway/MySQL.js.map +1 -1
- package/lib/Railway/Postgres.d.ts +1 -1
- package/lib/Railway/Postgres.d.ts.map +1 -1
- package/lib/Railway/Postgres.js +113 -95
- package/lib/Railway/Postgres.js.map +1 -1
- package/lib/Railway/PrivateNetwork.d.ts +87 -61
- package/lib/Railway/PrivateNetwork.d.ts.map +1 -1
- package/lib/Railway/PrivateNetwork.js +298 -196
- package/lib/Railway/PrivateNetwork.js.map +1 -1
- package/lib/Railway/Project.d.ts +80 -6
- package/lib/Railway/Project.d.ts.map +1 -1
- package/lib/Railway/Project.js +24 -17
- package/lib/Railway/Project.js.map +1 -1
- package/lib/Railway/ProjectEnvironment.d.ts +1 -1
- package/lib/Railway/ProjectEnvironment.d.ts.map +1 -1
- package/lib/Railway/ProjectEnvironment.js +22 -15
- package/lib/Railway/ProjectEnvironment.js.map +1 -1
- package/lib/Railway/Providers.d.ts.map +1 -1
- package/lib/Railway/Providers.js +3 -2
- package/lib/Railway/Providers.js.map +1 -1
- package/lib/Railway/Redis.d.ts +1 -1
- package/lib/Railway/Redis.d.ts.map +1 -1
- package/lib/Railway/Redis.js +53 -42
- package/lib/Railway/Redis.js.map +1 -1
- package/lib/Railway/RedisBinding.js +2 -2
- package/lib/Railway/Sandbox.d.ts +182 -16
- package/lib/Railway/Sandbox.d.ts.map +1 -1
- package/lib/Railway/Sandbox.js +112 -53
- package/lib/Railway/Sandbox.js.map +1 -1
- package/lib/Railway/SandboxCheckpoint.d.ts +84 -0
- package/lib/Railway/SandboxCheckpoint.d.ts.map +1 -0
- package/lib/Railway/SandboxCheckpoint.js +189 -0
- package/lib/Railway/SandboxCheckpoint.js.map +1 -0
- package/lib/Railway/Service.d.ts +3 -1
- package/lib/Railway/Service.d.ts.map +1 -1
- package/lib/Railway/Service.js.map +1 -1
- package/lib/Railway/ServiceDomain.d.ts +79 -6
- package/lib/Railway/ServiceDomain.d.ts.map +1 -1
- package/lib/Railway/ServiceDomain.js +29 -49
- package/lib/Railway/ServiceDomain.js.map +1 -1
- package/lib/Railway/ServiceProvider.d.ts +1 -1
- package/lib/Railway/ServiceProvider.d.ts.map +1 -1
- package/lib/Railway/ServiceProvider.js +115 -65
- package/lib/Railway/ServiceProvider.js.map +1 -1
- package/lib/Railway/TcpProxy.d.ts +1 -1
- package/lib/Railway/TcpProxy.d.ts.map +1 -1
- package/lib/Railway/TcpProxy.js +24 -16
- package/lib/Railway/TcpProxy.js.map +1 -1
- package/lib/Railway/Template.d.ts +5 -5
- package/lib/Railway/Template.d.ts.map +1 -1
- package/lib/Railway/Template.js +83 -56
- package/lib/Railway/Template.js.map +1 -1
- package/lib/Railway/Usage.d.ts +82 -5
- package/lib/Railway/Usage.d.ts.map +1 -1
- package/lib/Railway/Usage.js +28 -12
- package/lib/Railway/Usage.js.map +1 -1
- package/lib/Railway/Variable.d.ts +1 -1
- package/lib/Railway/Variable.d.ts.map +1 -1
- package/lib/Railway/Variable.js +8 -10
- package/lib/Railway/Variable.js.map +1 -1
- package/lib/Railway/Volume.d.ts +77 -3
- package/lib/Railway/Volume.d.ts.map +1 -1
- package/lib/Railway/Volume.js +67 -35
- package/lib/Railway/Volume.js.map +1 -1
- package/lib/Railway/VolumeBackup.d.ts +20 -4
- package/lib/Railway/VolumeBackup.d.ts.map +1 -1
- package/lib/Railway/VolumeBackup.js +47 -28
- package/lib/Railway/VolumeBackup.js.map +1 -1
- package/lib/Railway/Website/Cdn.d.ts +18 -2
- package/lib/Railway/Website/Cdn.d.ts.map +1 -1
- package/lib/Railway/Website/Cdn.js +82 -35
- package/lib/Railway/Website/Cdn.js.map +1 -1
- package/lib/Railway/hosted.d.ts.map +1 -1
- package/lib/Railway/hosted.js +10 -3
- package/lib/Railway/hosted.js.map +1 -1
- package/lib/Railway/index.d.ts +1 -0
- package/lib/Railway/index.d.ts.map +1 -1
- package/lib/Railway/index.js +1 -0
- package/lib/Railway/index.js.map +1 -1
- package/lib/Railway/transient.d.ts +6 -16
- package/lib/Railway/transient.d.ts.map +1 -1
- package/lib/Railway/transient.js +20 -32
- package/lib/Railway/transient.js.map +1 -1
- package/lib/Rpc.d.ts +22 -1
- package/lib/Rpc.d.ts.map +1 -1
- package/lib/Rpc.js +37 -2
- package/lib/Rpc.js.map +1 -1
- package/lib/Runtime/Bootstrap/Process.js +2 -2
- package/lib/Runtime.d.ts +1 -1
- package/lib/Runtime.js +1 -1
- package/lib/RuntimeContext.d.ts +1 -1
- package/lib/RuntimeContext.js +1 -1
- package/lib/SQL/Postgres.d.ts.map +1 -1
- package/lib/SQL/Postgres.js +5 -1
- package/lib/SQL/Postgres.js.map +1 -1
- package/lib/SQL/PostgresTls.d.ts +29 -0
- package/lib/SQL/PostgresTls.d.ts.map +1 -0
- package/lib/SQL/PostgresTls.js +63 -0
- package/lib/SQL/PostgresTls.js.map +1 -0
- package/lib/Server/Process.js +1 -1
- package/lib/Server/index.d.ts +0 -2
- package/lib/Server/index.d.ts.map +1 -1
- package/lib/Server/index.js +0 -2
- package/lib/Server/index.js.map +1 -1
- package/lib/Stack.d.ts.map +1 -1
- package/lib/Stack.js +2 -1
- package/lib/Stack.js.map +1 -1
- package/lib/StackContext.d.ts +4 -0
- package/lib/StackContext.d.ts.map +1 -0
- package/lib/StackContext.js +3 -0
- package/lib/StackContext.js.map +1 -0
- package/lib/State/HttpStateApi.d.ts +8 -8
- package/lib/State/HttpStateStore.d.ts +5 -10
- package/lib/State/HttpStateStore.d.ts.map +1 -1
- package/lib/State/HttpStateStore.js +18 -32
- package/lib/State/HttpStateStore.js.map +1 -1
- package/lib/State/PostgresState.d.ts +4 -4
- package/lib/State/PostgresState.d.ts.map +1 -1
- package/lib/State/PostgresState.js +5 -4
- package/lib/State/PostgresState.js.map +1 -1
- package/lib/State/State.d.ts +5 -0
- package/lib/State/State.d.ts.map +1 -1
- package/lib/State/State.js.map +1 -1
- package/lib/Stripe/Account.d.ts +308 -0
- package/lib/Stripe/Account.d.ts.map +1 -0
- package/lib/Stripe/Account.js +436 -0
- package/lib/Stripe/Account.js.map +1 -0
- package/lib/Stripe/AccountExternalAccount.d.ts +139 -0
- package/lib/Stripe/AccountExternalAccount.d.ts.map +1 -0
- package/lib/Stripe/AccountExternalAccount.js +354 -0
- package/lib/Stripe/AccountExternalAccount.js.map +1 -0
- package/lib/Stripe/AccountPerson.d.ts +142 -0
- package/lib/Stripe/AccountPerson.d.ts.map +1 -0
- package/lib/Stripe/AccountPerson.js +354 -0
- package/lib/Stripe/AccountPerson.js.map +1 -0
- package/lib/Stripe/Alert.d.ts +168 -0
- package/lib/Stripe/Alert.d.ts.map +1 -0
- package/lib/Stripe/Alert.js +285 -0
- package/lib/Stripe/Alert.js.map +1 -0
- package/lib/Stripe/ApplePayDomain.d.ts +75 -0
- package/lib/Stripe/ApplePayDomain.d.ts.map +1 -0
- package/lib/Stripe/ApplePayDomain.js +178 -0
- package/lib/Stripe/ApplePayDomain.js.map +1 -0
- package/lib/Stripe/AppsSecret.d.ts +120 -0
- package/lib/Stripe/AppsSecret.d.ts.map +1 -0
- package/lib/Stripe/AppsSecret.js +232 -0
- package/lib/Stripe/AppsSecret.js.map +1 -0
- package/lib/Stripe/AuthProvider.d.ts +27 -0
- package/lib/Stripe/AuthProvider.d.ts.map +1 -0
- package/lib/Stripe/AuthProvider.js +56 -0
- package/lib/Stripe/AuthProvider.js.map +1 -0
- package/lib/Stripe/BillingMeter.d.ts +168 -0
- package/lib/Stripe/BillingMeter.d.ts.map +1 -0
- package/lib/Stripe/BillingMeter.js +270 -0
- package/lib/Stripe/BillingMeter.js.map +1 -0
- package/lib/Stripe/BillingPortalConfiguration.d.ts +358 -0
- package/lib/Stripe/BillingPortalConfiguration.d.ts.map +1 -0
- package/lib/Stripe/BillingPortalConfiguration.js +480 -0
- package/lib/Stripe/BillingPortalConfiguration.js.map +1 -0
- package/lib/Stripe/ConsumeEvents.d.ts +80 -0
- package/lib/Stripe/ConsumeEvents.d.ts.map +1 -0
- package/lib/Stripe/ConsumeEvents.js +139 -0
- package/lib/Stripe/ConsumeEvents.js.map +1 -0
- package/lib/Stripe/Coupon.d.ts +179 -0
- package/lib/Stripe/Coupon.d.ts.map +1 -0
- package/lib/Stripe/Coupon.js +323 -0
- package/lib/Stripe/Coupon.js.map +1 -0
- package/lib/Stripe/CreateAccount.d.ts +25 -0
- package/lib/Stripe/CreateAccount.d.ts.map +1 -0
- package/lib/Stripe/CreateAccount.js +3 -0
- package/lib/Stripe/CreateAccount.js.map +1 -0
- package/lib/Stripe/CreateAccountHttp.d.ts +11 -0
- package/lib/Stripe/CreateAccountHttp.d.ts.map +1 -0
- package/lib/Stripe/CreateAccountHttp.js +17 -0
- package/lib/Stripe/CreateAccountHttp.js.map +1 -0
- package/lib/Stripe/CreateAccountLink.d.ts +29 -0
- package/lib/Stripe/CreateAccountLink.d.ts.map +1 -0
- package/lib/Stripe/CreateAccountLink.js +3 -0
- package/lib/Stripe/CreateAccountLink.js.map +1 -0
- package/lib/Stripe/CreateAccountLinkHttp.d.ts +11 -0
- package/lib/Stripe/CreateAccountLinkHttp.d.ts.map +1 -0
- package/lib/Stripe/CreateAccountLinkHttp.js +17 -0
- package/lib/Stripe/CreateAccountLinkHttp.js.map +1 -0
- package/lib/Stripe/CreateAppsSecret.d.ts +25 -0
- package/lib/Stripe/CreateAppsSecret.d.ts.map +1 -0
- package/lib/Stripe/CreateAppsSecret.js +3 -0
- package/lib/Stripe/CreateAppsSecret.js.map +1 -0
- package/lib/Stripe/CreateAppsSecretHttp.d.ts +11 -0
- package/lib/Stripe/CreateAppsSecretHttp.d.ts.map +1 -0
- package/lib/Stripe/CreateAppsSecretHttp.js +17 -0
- package/lib/Stripe/CreateAppsSecretHttp.js.map +1 -0
- package/lib/Stripe/CreateBillingPortalSession.d.ts +33 -0
- package/lib/Stripe/CreateBillingPortalSession.d.ts.map +1 -0
- package/lib/Stripe/CreateBillingPortalSession.js +3 -0
- package/lib/Stripe/CreateBillingPortalSession.js.map +1 -0
- package/lib/Stripe/CreateBillingPortalSessionHttp.d.ts +11 -0
- package/lib/Stripe/CreateBillingPortalSessionHttp.d.ts.map +1 -0
- package/lib/Stripe/CreateBillingPortalSessionHttp.js +17 -0
- package/lib/Stripe/CreateBillingPortalSessionHttp.js.map +1 -0
- package/lib/Stripe/CreateCheckoutSession.d.ts +35 -0
- package/lib/Stripe/CreateCheckoutSession.d.ts.map +1 -0
- package/lib/Stripe/CreateCheckoutSession.js +3 -0
- package/lib/Stripe/CreateCheckoutSession.js.map +1 -0
- package/lib/Stripe/CreateCheckoutSessionHttp.d.ts +11 -0
- package/lib/Stripe/CreateCheckoutSessionHttp.d.ts.map +1 -0
- package/lib/Stripe/CreateCheckoutSessionHttp.js +17 -0
- package/lib/Stripe/CreateCheckoutSessionHttp.js.map +1 -0
- package/lib/Stripe/CreateCreditGrant.d.ts +27 -0
- package/lib/Stripe/CreateCreditGrant.d.ts.map +1 -0
- package/lib/Stripe/CreateCreditGrant.js +3 -0
- package/lib/Stripe/CreateCreditGrant.js.map +1 -0
- package/lib/Stripe/CreateCreditGrantHttp.d.ts +11 -0
- package/lib/Stripe/CreateCreditGrantHttp.d.ts.map +1 -0
- package/lib/Stripe/CreateCreditGrantHttp.js +17 -0
- package/lib/Stripe/CreateCreditGrantHttp.js.map +1 -0
- package/lib/Stripe/CreateCustomer.d.ts +24 -0
- package/lib/Stripe/CreateCustomer.d.ts.map +1 -0
- package/lib/Stripe/CreateCustomer.js +3 -0
- package/lib/Stripe/CreateCustomer.js.map +1 -0
- package/lib/Stripe/CreateCustomerHttp.d.ts +11 -0
- package/lib/Stripe/CreateCustomerHttp.d.ts.map +1 -0
- package/lib/Stripe/CreateCustomerHttp.js +17 -0
- package/lib/Stripe/CreateCustomerHttp.js.map +1 -0
- package/lib/Stripe/CreateFileLink.d.ts +23 -0
- package/lib/Stripe/CreateFileLink.d.ts.map +1 -0
- package/lib/Stripe/CreateFileLink.js +3 -0
- package/lib/Stripe/CreateFileLink.js.map +1 -0
- package/lib/Stripe/CreateFileLinkHttp.d.ts +11 -0
- package/lib/Stripe/CreateFileLinkHttp.d.ts.map +1 -0
- package/lib/Stripe/CreateFileLinkHttp.js +17 -0
- package/lib/Stripe/CreateFileLinkHttp.js.map +1 -0
- package/lib/Stripe/CreateIssuingCard.d.ts +25 -0
- package/lib/Stripe/CreateIssuingCard.d.ts.map +1 -0
- package/lib/Stripe/CreateIssuingCard.js +3 -0
- package/lib/Stripe/CreateIssuingCard.js.map +1 -0
- package/lib/Stripe/CreateIssuingCardHttp.d.ts +11 -0
- package/lib/Stripe/CreateIssuingCardHttp.d.ts.map +1 -0
- package/lib/Stripe/CreateIssuingCardHttp.js +17 -0
- package/lib/Stripe/CreateIssuingCardHttp.js.map +1 -0
- package/lib/Stripe/CreateIssuingCardholder.d.ts +32 -0
- package/lib/Stripe/CreateIssuingCardholder.d.ts.map +1 -0
- package/lib/Stripe/CreateIssuingCardholder.js +3 -0
- package/lib/Stripe/CreateIssuingCardholder.js.map +1 -0
- package/lib/Stripe/CreateIssuingCardholderHttp.d.ts +11 -0
- package/lib/Stripe/CreateIssuingCardholderHttp.d.ts.map +1 -0
- package/lib/Stripe/CreateIssuingCardholderHttp.js +17 -0
- package/lib/Stripe/CreateIssuingCardholderHttp.js.map +1 -0
- package/lib/Stripe/CreateTerminalReader.d.ts +25 -0
- package/lib/Stripe/CreateTerminalReader.d.ts.map +1 -0
- package/lib/Stripe/CreateTerminalReader.js +3 -0
- package/lib/Stripe/CreateTerminalReader.js.map +1 -0
- package/lib/Stripe/CreateTerminalReaderHttp.d.ts +11 -0
- package/lib/Stripe/CreateTerminalReaderHttp.d.ts.map +1 -0
- package/lib/Stripe/CreateTerminalReaderHttp.js +17 -0
- package/lib/Stripe/CreateTerminalReaderHttp.js.map +1 -0
- package/lib/Stripe/Credentials.d.ts +15 -0
- package/lib/Stripe/Credentials.d.ts.map +1 -0
- package/lib/Stripe/Credentials.js +27 -0
- package/lib/Stripe/Credentials.js.map +1 -0
- package/lib/Stripe/CreditGrant.d.ts +219 -0
- package/lib/Stripe/CreditGrant.d.ts.map +1 -0
- package/lib/Stripe/CreditGrant.js +364 -0
- package/lib/Stripe/CreditGrant.js.map +1 -0
- package/lib/Stripe/Customer.d.ts +90 -0
- package/lib/Stripe/Customer.d.ts.map +1 -0
- package/lib/Stripe/Customer.js +203 -0
- package/lib/Stripe/Customer.js.map +1 -0
- package/lib/Stripe/CustomerTaxId.d.ts +81 -0
- package/lib/Stripe/CustomerTaxId.d.ts.map +1 -0
- package/lib/Stripe/CustomerTaxId.js +228 -0
- package/lib/Stripe/CustomerTaxId.js.map +1 -0
- package/lib/Stripe/EntitlementsFeature.d.ts +96 -0
- package/lib/Stripe/EntitlementsFeature.d.ts.map +1 -0
- package/lib/Stripe/EntitlementsFeature.js +261 -0
- package/lib/Stripe/EntitlementsFeature.js.map +1 -0
- package/lib/Stripe/Events.d.ts +91 -0
- package/lib/Stripe/Events.d.ts.map +1 -0
- package/lib/Stripe/Events.js +102 -0
- package/lib/Stripe/Events.js.map +1 -0
- package/lib/Stripe/FileLink.d.ts +92 -0
- package/lib/Stripe/FileLink.d.ts.map +1 -0
- package/lib/Stripe/FileLink.js +229 -0
- package/lib/Stripe/FileLink.js.map +1 -0
- package/lib/Stripe/IssuingCard.d.ts +249 -0
- package/lib/Stripe/IssuingCard.d.ts.map +1 -0
- package/lib/Stripe/IssuingCard.js +423 -0
- package/lib/Stripe/IssuingCard.js.map +1 -0
- package/lib/Stripe/IssuingCardholder.d.ts +366 -0
- package/lib/Stripe/IssuingCardholder.d.ts.map +1 -0
- package/lib/Stripe/IssuingCardholder.js +520 -0
- package/lib/Stripe/IssuingCardholder.js.map +1 -0
- package/lib/Stripe/IssuingPersonalizationDesign.d.ts +185 -0
- package/lib/Stripe/IssuingPersonalizationDesign.d.ts.map +1 -0
- package/lib/Stripe/IssuingPersonalizationDesign.js +340 -0
- package/lib/Stripe/IssuingPersonalizationDesign.js.map +1 -0
- package/lib/Stripe/Metadata.d.ts +39 -0
- package/lib/Stripe/Metadata.d.ts.map +1 -0
- package/lib/Stripe/Metadata.js +58 -0
- package/lib/Stripe/Metadata.js.map +1 -0
- package/lib/Stripe/PaymentLink.d.ts +219 -0
- package/lib/Stripe/PaymentLink.d.ts.map +1 -0
- package/lib/Stripe/PaymentLink.js +491 -0
- package/lib/Stripe/PaymentLink.js.map +1 -0
- package/lib/Stripe/PaymentMethodConfiguration.d.ts +269 -0
- package/lib/Stripe/PaymentMethodConfiguration.d.ts.map +1 -0
- package/lib/Stripe/PaymentMethodConfiguration.js +330 -0
- package/lib/Stripe/PaymentMethodConfiguration.js.map +1 -0
- package/lib/Stripe/PaymentMethodDomain.d.ts +118 -0
- package/lib/Stripe/PaymentMethodDomain.d.ts.map +1 -0
- package/lib/Stripe/PaymentMethodDomain.js +209 -0
- package/lib/Stripe/PaymentMethodDomain.js.map +1 -0
- package/lib/Stripe/Plan.d.ts +175 -0
- package/lib/Stripe/Plan.d.ts.map +1 -0
- package/lib/Stripe/Plan.js +305 -0
- package/lib/Stripe/Plan.js.map +1 -0
- package/lib/Stripe/Price.d.ts +176 -0
- package/lib/Stripe/Price.d.ts.map +1 -0
- package/lib/Stripe/Price.js +344 -0
- package/lib/Stripe/Price.js.map +1 -0
- package/lib/Stripe/Product.d.ts +92 -0
- package/lib/Stripe/Product.d.ts.map +1 -0
- package/lib/Stripe/Product.js +222 -0
- package/lib/Stripe/Product.js.map +1 -0
- package/lib/Stripe/ProductFeature.d.ts +70 -0
- package/lib/Stripe/ProductFeature.d.ts.map +1 -0
- package/lib/Stripe/ProductFeature.js +206 -0
- package/lib/Stripe/ProductFeature.js.map +1 -0
- package/lib/Stripe/PromotionCode.d.ts +168 -0
- package/lib/Stripe/PromotionCode.d.ts.map +1 -0
- package/lib/Stripe/PromotionCode.js +396 -0
- package/lib/Stripe/PromotionCode.js.map +1 -0
- package/lib/Stripe/Providers.d.ts +36 -0
- package/lib/Stripe/Providers.d.ts.map +1 -0
- package/lib/Stripe/Providers.js +162 -0
- package/lib/Stripe/Providers.js.map +1 -0
- package/lib/Stripe/RadarValueList.d.ts +112 -0
- package/lib/Stripe/RadarValueList.d.ts.map +1 -0
- package/lib/Stripe/RadarValueList.js +259 -0
- package/lib/Stripe/RadarValueList.js.map +1 -0
- package/lib/Stripe/RadarValueListItem.d.ts +69 -0
- package/lib/Stripe/RadarValueListItem.d.ts.map +1 -0
- package/lib/Stripe/RadarValueListItem.js +213 -0
- package/lib/Stripe/RadarValueListItem.js.map +1 -0
- package/lib/Stripe/RestrictedApiKey.d.ts +85 -0
- package/lib/Stripe/RestrictedApiKey.d.ts.map +1 -0
- package/lib/Stripe/RestrictedApiKey.js +91 -0
- package/lib/Stripe/RestrictedApiKey.js.map +1 -0
- package/lib/Stripe/RetrieveAccount.d.ts +23 -0
- package/lib/Stripe/RetrieveAccount.d.ts.map +1 -0
- package/lib/Stripe/RetrieveAccount.js +3 -0
- package/lib/Stripe/RetrieveAccount.js.map +1 -0
- package/lib/Stripe/RetrieveAccountExternalAccount.d.ts +23 -0
- package/lib/Stripe/RetrieveAccountExternalAccount.d.ts.map +1 -0
- package/lib/Stripe/RetrieveAccountExternalAccount.js +3 -0
- package/lib/Stripe/RetrieveAccountExternalAccount.js.map +1 -0
- package/lib/Stripe/RetrieveAccountExternalAccountHttp.d.ts +11 -0
- package/lib/Stripe/RetrieveAccountExternalAccountHttp.d.ts.map +1 -0
- package/lib/Stripe/RetrieveAccountExternalAccountHttp.js +31 -0
- package/lib/Stripe/RetrieveAccountExternalAccountHttp.js.map +1 -0
- package/lib/Stripe/RetrieveAccountHttp.d.ts +11 -0
- package/lib/Stripe/RetrieveAccountHttp.d.ts.map +1 -0
- package/lib/Stripe/RetrieveAccountHttp.js +18 -0
- package/lib/Stripe/RetrieveAccountHttp.js.map +1 -0
- package/lib/Stripe/RetrieveAccountPerson.d.ts +23 -0
- package/lib/Stripe/RetrieveAccountPerson.d.ts.map +1 -0
- package/lib/Stripe/RetrieveAccountPerson.js +3 -0
- package/lib/Stripe/RetrieveAccountPerson.js.map +1 -0
- package/lib/Stripe/RetrieveAccountPersonHttp.d.ts +11 -0
- package/lib/Stripe/RetrieveAccountPersonHttp.d.ts.map +1 -0
- package/lib/Stripe/RetrieveAccountPersonHttp.js +31 -0
- package/lib/Stripe/RetrieveAccountPersonHttp.js.map +1 -0
- package/lib/Stripe/RetrieveAlert.d.ts +23 -0
- package/lib/Stripe/RetrieveAlert.d.ts.map +1 -0
- package/lib/Stripe/RetrieveAlert.js +3 -0
- package/lib/Stripe/RetrieveAlert.js.map +1 -0
- package/lib/Stripe/RetrieveAlertHttp.d.ts +10 -0
- package/lib/Stripe/RetrieveAlertHttp.d.ts.map +1 -0
- package/lib/Stripe/RetrieveAlertHttp.js +17 -0
- package/lib/Stripe/RetrieveAlertHttp.js.map +1 -0
- package/lib/Stripe/RetrieveApplePayDomain.d.ts +23 -0
- package/lib/Stripe/RetrieveApplePayDomain.d.ts.map +1 -0
- package/lib/Stripe/RetrieveApplePayDomain.js +3 -0
- package/lib/Stripe/RetrieveApplePayDomain.js.map +1 -0
- package/lib/Stripe/RetrieveApplePayDomainHttp.d.ts +11 -0
- package/lib/Stripe/RetrieveApplePayDomainHttp.d.ts.map +1 -0
- package/lib/Stripe/RetrieveApplePayDomainHttp.js +18 -0
- package/lib/Stripe/RetrieveApplePayDomainHttp.js.map +1 -0
- package/lib/Stripe/RetrieveAppsSecret.d.ts +24 -0
- package/lib/Stripe/RetrieveAppsSecret.d.ts.map +1 -0
- package/lib/Stripe/RetrieveAppsSecret.js +3 -0
- package/lib/Stripe/RetrieveAppsSecret.js.map +1 -0
- package/lib/Stripe/RetrieveAppsSecretHttp.d.ts +11 -0
- package/lib/Stripe/RetrieveAppsSecretHttp.d.ts.map +1 -0
- package/lib/Stripe/RetrieveAppsSecretHttp.js +36 -0
- package/lib/Stripe/RetrieveAppsSecretHttp.js.map +1 -0
- package/lib/Stripe/RetrieveBillingMeter.d.ts +23 -0
- package/lib/Stripe/RetrieveBillingMeter.d.ts.map +1 -0
- package/lib/Stripe/RetrieveBillingMeter.js +3 -0
- package/lib/Stripe/RetrieveBillingMeter.js.map +1 -0
- package/lib/Stripe/RetrieveBillingMeterHttp.d.ts +10 -0
- package/lib/Stripe/RetrieveBillingMeterHttp.d.ts.map +1 -0
- package/lib/Stripe/RetrieveBillingMeterHttp.js +17 -0
- package/lib/Stripe/RetrieveBillingMeterHttp.js.map +1 -0
- package/lib/Stripe/RetrieveBillingPortalConfiguration.d.ts +23 -0
- package/lib/Stripe/RetrieveBillingPortalConfiguration.d.ts.map +1 -0
- package/lib/Stripe/RetrieveBillingPortalConfiguration.js +3 -0
- package/lib/Stripe/RetrieveBillingPortalConfiguration.js.map +1 -0
- package/lib/Stripe/RetrieveBillingPortalConfigurationHttp.d.ts +10 -0
- package/lib/Stripe/RetrieveBillingPortalConfigurationHttp.d.ts.map +1 -0
- package/lib/Stripe/RetrieveBillingPortalConfigurationHttp.js +17 -0
- package/lib/Stripe/RetrieveBillingPortalConfigurationHttp.js.map +1 -0
- package/lib/Stripe/RetrieveCoupon.d.ts +23 -0
- package/lib/Stripe/RetrieveCoupon.d.ts.map +1 -0
- package/lib/Stripe/RetrieveCoupon.js +3 -0
- package/lib/Stripe/RetrieveCoupon.js.map +1 -0
- package/lib/Stripe/RetrieveCouponHttp.d.ts +11 -0
- package/lib/Stripe/RetrieveCouponHttp.d.ts.map +1 -0
- package/lib/Stripe/RetrieveCouponHttp.js +18 -0
- package/lib/Stripe/RetrieveCouponHttp.js.map +1 -0
- package/lib/Stripe/RetrieveCreditGrant.d.ts +23 -0
- package/lib/Stripe/RetrieveCreditGrant.d.ts.map +1 -0
- package/lib/Stripe/RetrieveCreditGrant.js +3 -0
- package/lib/Stripe/RetrieveCreditGrant.js.map +1 -0
- package/lib/Stripe/RetrieveCreditGrantHttp.d.ts +11 -0
- package/lib/Stripe/RetrieveCreditGrantHttp.d.ts.map +1 -0
- package/lib/Stripe/RetrieveCreditGrantHttp.js +18 -0
- package/lib/Stripe/RetrieveCreditGrantHttp.js.map +1 -0
- package/lib/Stripe/RetrieveCustomer.d.ts +23 -0
- package/lib/Stripe/RetrieveCustomer.d.ts.map +1 -0
- package/lib/Stripe/RetrieveCustomer.js +3 -0
- package/lib/Stripe/RetrieveCustomer.js.map +1 -0
- package/lib/Stripe/RetrieveCustomerHttp.d.ts +11 -0
- package/lib/Stripe/RetrieveCustomerHttp.d.ts.map +1 -0
- package/lib/Stripe/RetrieveCustomerHttp.js +18 -0
- package/lib/Stripe/RetrieveCustomerHttp.js.map +1 -0
- package/lib/Stripe/RetrieveCustomerTaxId.d.ts +23 -0
- package/lib/Stripe/RetrieveCustomerTaxId.d.ts.map +1 -0
- package/lib/Stripe/RetrieveCustomerTaxId.js +3 -0
- package/lib/Stripe/RetrieveCustomerTaxId.js.map +1 -0
- package/lib/Stripe/RetrieveCustomerTaxIdHttp.d.ts +11 -0
- package/lib/Stripe/RetrieveCustomerTaxIdHttp.d.ts.map +1 -0
- package/lib/Stripe/RetrieveCustomerTaxIdHttp.js +31 -0
- package/lib/Stripe/RetrieveCustomerTaxIdHttp.js.map +1 -0
- package/lib/Stripe/RetrieveEntitlementsFeature.d.ts +23 -0
- package/lib/Stripe/RetrieveEntitlementsFeature.d.ts.map +1 -0
- package/lib/Stripe/RetrieveEntitlementsFeature.js +3 -0
- package/lib/Stripe/RetrieveEntitlementsFeature.js.map +1 -0
- package/lib/Stripe/RetrieveEntitlementsFeatureHttp.d.ts +10 -0
- package/lib/Stripe/RetrieveEntitlementsFeatureHttp.d.ts.map +1 -0
- package/lib/Stripe/RetrieveEntitlementsFeatureHttp.js +17 -0
- package/lib/Stripe/RetrieveEntitlementsFeatureHttp.js.map +1 -0
- package/lib/Stripe/RetrieveFileLink.d.ts +23 -0
- package/lib/Stripe/RetrieveFileLink.d.ts.map +1 -0
- package/lib/Stripe/RetrieveFileLink.js +3 -0
- package/lib/Stripe/RetrieveFileLink.js.map +1 -0
- package/lib/Stripe/RetrieveFileLinkHttp.d.ts +11 -0
- package/lib/Stripe/RetrieveFileLinkHttp.d.ts.map +1 -0
- package/lib/Stripe/RetrieveFileLinkHttp.js +18 -0
- package/lib/Stripe/RetrieveFileLinkHttp.js.map +1 -0
- package/lib/Stripe/RetrieveIssuingCard.d.ts +23 -0
- package/lib/Stripe/RetrieveIssuingCard.d.ts.map +1 -0
- package/lib/Stripe/RetrieveIssuingCard.js +3 -0
- package/lib/Stripe/RetrieveIssuingCard.js.map +1 -0
- package/lib/Stripe/RetrieveIssuingCardHttp.d.ts +11 -0
- package/lib/Stripe/RetrieveIssuingCardHttp.d.ts.map +1 -0
- package/lib/Stripe/RetrieveIssuingCardHttp.js +18 -0
- package/lib/Stripe/RetrieveIssuingCardHttp.js.map +1 -0
- package/lib/Stripe/RetrieveIssuingCardholder.d.ts +23 -0
- package/lib/Stripe/RetrieveIssuingCardholder.d.ts.map +1 -0
- package/lib/Stripe/RetrieveIssuingCardholder.js +3 -0
- package/lib/Stripe/RetrieveIssuingCardholder.js.map +1 -0
- package/lib/Stripe/RetrieveIssuingCardholderHttp.d.ts +11 -0
- package/lib/Stripe/RetrieveIssuingCardholderHttp.d.ts.map +1 -0
- package/lib/Stripe/RetrieveIssuingCardholderHttp.js +18 -0
- package/lib/Stripe/RetrieveIssuingCardholderHttp.js.map +1 -0
- package/lib/Stripe/RetrieveIssuingPersonalizationDesign.d.ts +23 -0
- package/lib/Stripe/RetrieveIssuingPersonalizationDesign.d.ts.map +1 -0
- package/lib/Stripe/RetrieveIssuingPersonalizationDesign.js +3 -0
- package/lib/Stripe/RetrieveIssuingPersonalizationDesign.js.map +1 -0
- package/lib/Stripe/RetrieveIssuingPersonalizationDesignHttp.d.ts +11 -0
- package/lib/Stripe/RetrieveIssuingPersonalizationDesignHttp.d.ts.map +1 -0
- package/lib/Stripe/RetrieveIssuingPersonalizationDesignHttp.js +18 -0
- package/lib/Stripe/RetrieveIssuingPersonalizationDesignHttp.js.map +1 -0
- package/lib/Stripe/RetrievePaymentLink.d.ts +23 -0
- package/lib/Stripe/RetrievePaymentLink.d.ts.map +1 -0
- package/lib/Stripe/RetrievePaymentLink.js +3 -0
- package/lib/Stripe/RetrievePaymentLink.js.map +1 -0
- package/lib/Stripe/RetrievePaymentLinkHttp.d.ts +11 -0
- package/lib/Stripe/RetrievePaymentLinkHttp.d.ts.map +1 -0
- package/lib/Stripe/RetrievePaymentLinkHttp.js +18 -0
- package/lib/Stripe/RetrievePaymentLinkHttp.js.map +1 -0
- package/lib/Stripe/RetrievePaymentMethodConfiguration.d.ts +23 -0
- package/lib/Stripe/RetrievePaymentMethodConfiguration.d.ts.map +1 -0
- package/lib/Stripe/RetrievePaymentMethodConfiguration.js +3 -0
- package/lib/Stripe/RetrievePaymentMethodConfiguration.js.map +1 -0
- package/lib/Stripe/RetrievePaymentMethodConfigurationHttp.d.ts +10 -0
- package/lib/Stripe/RetrievePaymentMethodConfigurationHttp.d.ts.map +1 -0
- package/lib/Stripe/RetrievePaymentMethodConfigurationHttp.js +17 -0
- package/lib/Stripe/RetrievePaymentMethodConfigurationHttp.js.map +1 -0
- package/lib/Stripe/RetrievePaymentMethodDomain.d.ts +23 -0
- package/lib/Stripe/RetrievePaymentMethodDomain.d.ts.map +1 -0
- package/lib/Stripe/RetrievePaymentMethodDomain.js +3 -0
- package/lib/Stripe/RetrievePaymentMethodDomain.js.map +1 -0
- package/lib/Stripe/RetrievePaymentMethodDomainHttp.d.ts +10 -0
- package/lib/Stripe/RetrievePaymentMethodDomainHttp.d.ts.map +1 -0
- package/lib/Stripe/RetrievePaymentMethodDomainHttp.js +17 -0
- package/lib/Stripe/RetrievePaymentMethodDomainHttp.js.map +1 -0
- package/lib/Stripe/RetrievePlan.d.ts +23 -0
- package/lib/Stripe/RetrievePlan.d.ts.map +1 -0
- package/lib/Stripe/RetrievePlan.js +3 -0
- package/lib/Stripe/RetrievePlan.js.map +1 -0
- package/lib/Stripe/RetrievePlanHttp.d.ts +11 -0
- package/lib/Stripe/RetrievePlanHttp.d.ts.map +1 -0
- package/lib/Stripe/RetrievePlanHttp.js +18 -0
- package/lib/Stripe/RetrievePlanHttp.js.map +1 -0
- package/lib/Stripe/RetrievePrice.d.ts +23 -0
- package/lib/Stripe/RetrievePrice.d.ts.map +1 -0
- package/lib/Stripe/RetrievePrice.js +3 -0
- package/lib/Stripe/RetrievePrice.js.map +1 -0
- package/lib/Stripe/RetrievePriceHttp.d.ts +11 -0
- package/lib/Stripe/RetrievePriceHttp.d.ts.map +1 -0
- package/lib/Stripe/RetrievePriceHttp.js +18 -0
- package/lib/Stripe/RetrievePriceHttp.js.map +1 -0
- package/lib/Stripe/RetrieveProduct.d.ts +30 -0
- package/lib/Stripe/RetrieveProduct.d.ts.map +1 -0
- package/lib/Stripe/RetrieveProduct.js +3 -0
- package/lib/Stripe/RetrieveProduct.js.map +1 -0
- package/lib/Stripe/RetrieveProductFeature.d.ts +23 -0
- package/lib/Stripe/RetrieveProductFeature.d.ts.map +1 -0
- package/lib/Stripe/RetrieveProductFeature.js +3 -0
- package/lib/Stripe/RetrieveProductFeature.js.map +1 -0
- package/lib/Stripe/RetrieveProductFeatureHttp.d.ts +11 -0
- package/lib/Stripe/RetrieveProductFeatureHttp.d.ts.map +1 -0
- package/lib/Stripe/RetrieveProductFeatureHttp.js +31 -0
- package/lib/Stripe/RetrieveProductFeatureHttp.js.map +1 -0
- package/lib/Stripe/RetrieveProductHttp.d.ts +12 -0
- package/lib/Stripe/RetrieveProductHttp.d.ts.map +1 -0
- package/lib/Stripe/RetrieveProductHttp.js +33 -0
- package/lib/Stripe/RetrieveProductHttp.js.map +1 -0
- package/lib/Stripe/RetrievePromotionCode.d.ts +23 -0
- package/lib/Stripe/RetrievePromotionCode.d.ts.map +1 -0
- package/lib/Stripe/RetrievePromotionCode.js +3 -0
- package/lib/Stripe/RetrievePromotionCode.js.map +1 -0
- package/lib/Stripe/RetrievePromotionCodeHttp.d.ts +11 -0
- package/lib/Stripe/RetrievePromotionCodeHttp.d.ts.map +1 -0
- package/lib/Stripe/RetrievePromotionCodeHttp.js +18 -0
- package/lib/Stripe/RetrievePromotionCodeHttp.js.map +1 -0
- package/lib/Stripe/RetrieveRadarValueList.d.ts +23 -0
- package/lib/Stripe/RetrieveRadarValueList.d.ts.map +1 -0
- package/lib/Stripe/RetrieveRadarValueList.js +3 -0
- package/lib/Stripe/RetrieveRadarValueList.js.map +1 -0
- package/lib/Stripe/RetrieveRadarValueListHttp.d.ts +10 -0
- package/lib/Stripe/RetrieveRadarValueListHttp.d.ts.map +1 -0
- package/lib/Stripe/RetrieveRadarValueListHttp.js +17 -0
- package/lib/Stripe/RetrieveRadarValueListHttp.js.map +1 -0
- package/lib/Stripe/RetrieveRadarValueListItem.d.ts +23 -0
- package/lib/Stripe/RetrieveRadarValueListItem.d.ts.map +1 -0
- package/lib/Stripe/RetrieveRadarValueListItem.js +3 -0
- package/lib/Stripe/RetrieveRadarValueListItem.js.map +1 -0
- package/lib/Stripe/RetrieveRadarValueListItemHttp.d.ts +10 -0
- package/lib/Stripe/RetrieveRadarValueListItemHttp.d.ts.map +1 -0
- package/lib/Stripe/RetrieveRadarValueListItemHttp.js +17 -0
- package/lib/Stripe/RetrieveRadarValueListItemHttp.js.map +1 -0
- package/lib/Stripe/RetrieveShippingRate.d.ts +23 -0
- package/lib/Stripe/RetrieveShippingRate.d.ts.map +1 -0
- package/lib/Stripe/RetrieveShippingRate.js +3 -0
- package/lib/Stripe/RetrieveShippingRate.js.map +1 -0
- package/lib/Stripe/RetrieveShippingRateHttp.d.ts +11 -0
- package/lib/Stripe/RetrieveShippingRateHttp.d.ts.map +1 -0
- package/lib/Stripe/RetrieveShippingRateHttp.js +18 -0
- package/lib/Stripe/RetrieveShippingRateHttp.js.map +1 -0
- package/lib/Stripe/RetrieveTaxRate.d.ts +23 -0
- package/lib/Stripe/RetrieveTaxRate.d.ts.map +1 -0
- package/lib/Stripe/RetrieveTaxRate.js +3 -0
- package/lib/Stripe/RetrieveTaxRate.js.map +1 -0
- package/lib/Stripe/RetrieveTaxRateHttp.d.ts +11 -0
- package/lib/Stripe/RetrieveTaxRateHttp.d.ts.map +1 -0
- package/lib/Stripe/RetrieveTaxRateHttp.js +18 -0
- package/lib/Stripe/RetrieveTaxRateHttp.js.map +1 -0
- package/lib/Stripe/RetrieveTaxRegistration.d.ts +23 -0
- package/lib/Stripe/RetrieveTaxRegistration.d.ts.map +1 -0
- package/lib/Stripe/RetrieveTaxRegistration.js +3 -0
- package/lib/Stripe/RetrieveTaxRegistration.js.map +1 -0
- package/lib/Stripe/RetrieveTaxRegistrationHttp.d.ts +11 -0
- package/lib/Stripe/RetrieveTaxRegistrationHttp.d.ts.map +1 -0
- package/lib/Stripe/RetrieveTaxRegistrationHttp.js +18 -0
- package/lib/Stripe/RetrieveTaxRegistrationHttp.js.map +1 -0
- package/lib/Stripe/RetrieveTaxSettings.d.ts +25 -0
- package/lib/Stripe/RetrieveTaxSettings.d.ts.map +1 -0
- package/lib/Stripe/RetrieveTaxSettings.js +3 -0
- package/lib/Stripe/RetrieveTaxSettings.js.map +1 -0
- package/lib/Stripe/RetrieveTaxSettingsHttp.d.ts +12 -0
- package/lib/Stripe/RetrieveTaxSettingsHttp.d.ts.map +1 -0
- package/lib/Stripe/RetrieveTaxSettingsHttp.js +26 -0
- package/lib/Stripe/RetrieveTaxSettingsHttp.js.map +1 -0
- package/lib/Stripe/RetrieveTerminalConfiguration.d.ts +23 -0
- package/lib/Stripe/RetrieveTerminalConfiguration.d.ts.map +1 -0
- package/lib/Stripe/RetrieveTerminalConfiguration.js +3 -0
- package/lib/Stripe/RetrieveTerminalConfiguration.js.map +1 -0
- package/lib/Stripe/RetrieveTerminalConfigurationHttp.d.ts +11 -0
- package/lib/Stripe/RetrieveTerminalConfigurationHttp.d.ts.map +1 -0
- package/lib/Stripe/RetrieveTerminalConfigurationHttp.js +18 -0
- package/lib/Stripe/RetrieveTerminalConfigurationHttp.js.map +1 -0
- package/lib/Stripe/RetrieveTerminalLocation.d.ts +23 -0
- package/lib/Stripe/RetrieveTerminalLocation.d.ts.map +1 -0
- package/lib/Stripe/RetrieveTerminalLocation.js +3 -0
- package/lib/Stripe/RetrieveTerminalLocation.js.map +1 -0
- package/lib/Stripe/RetrieveTerminalLocationHttp.d.ts +11 -0
- package/lib/Stripe/RetrieveTerminalLocationHttp.d.ts.map +1 -0
- package/lib/Stripe/RetrieveTerminalLocationHttp.js +18 -0
- package/lib/Stripe/RetrieveTerminalLocationHttp.js.map +1 -0
- package/lib/Stripe/RetrieveTerminalReader.d.ts +23 -0
- package/lib/Stripe/RetrieveTerminalReader.d.ts.map +1 -0
- package/lib/Stripe/RetrieveTerminalReader.js +3 -0
- package/lib/Stripe/RetrieveTerminalReader.js.map +1 -0
- package/lib/Stripe/RetrieveTerminalReaderHttp.d.ts +11 -0
- package/lib/Stripe/RetrieveTerminalReaderHttp.d.ts.map +1 -0
- package/lib/Stripe/RetrieveTerminalReaderHttp.js +18 -0
- package/lib/Stripe/RetrieveTerminalReaderHttp.js.map +1 -0
- package/lib/Stripe/RetrieveWebhookEndpoint.d.ts +23 -0
- package/lib/Stripe/RetrieveWebhookEndpoint.d.ts.map +1 -0
- package/lib/Stripe/RetrieveWebhookEndpoint.js +3 -0
- package/lib/Stripe/RetrieveWebhookEndpoint.js.map +1 -0
- package/lib/Stripe/RetrieveWebhookEndpointHttp.d.ts +11 -0
- package/lib/Stripe/RetrieveWebhookEndpointHttp.d.ts.map +1 -0
- package/lib/Stripe/RetrieveWebhookEndpointHttp.js +18 -0
- package/lib/Stripe/RetrieveWebhookEndpointHttp.js.map +1 -0
- package/lib/Stripe/ShippingRate.d.ts +192 -0
- package/lib/Stripe/ShippingRate.d.ts.map +1 -0
- package/lib/Stripe/ShippingRate.js +375 -0
- package/lib/Stripe/ShippingRate.js.map +1 -0
- package/lib/Stripe/StripeHttp.d.ts +58 -0
- package/lib/Stripe/StripeHttp.d.ts.map +1 -0
- package/lib/Stripe/StripeHttp.js +110 -0
- package/lib/Stripe/StripeHttp.js.map +1 -0
- package/lib/Stripe/TaxRate.d.ts +153 -0
- package/lib/Stripe/TaxRate.d.ts.map +1 -0
- package/lib/Stripe/TaxRate.js +287 -0
- package/lib/Stripe/TaxRate.js.map +1 -0
- package/lib/Stripe/TaxRegistration.d.ts +275 -0
- package/lib/Stripe/TaxRegistration.d.ts.map +1 -0
- package/lib/Stripe/TaxRegistration.js +300 -0
- package/lib/Stripe/TaxRegistration.js.map +1 -0
- package/lib/Stripe/TaxSettings.d.ts +165 -0
- package/lib/Stripe/TaxSettings.d.ts.map +1 -0
- package/lib/Stripe/TaxSettings.js +207 -0
- package/lib/Stripe/TaxSettings.js.map +1 -0
- package/lib/Stripe/TerminalConfiguration.d.ts +368 -0
- package/lib/Stripe/TerminalConfiguration.d.ts.map +1 -0
- package/lib/Stripe/TerminalConfiguration.js +537 -0
- package/lib/Stripe/TerminalConfiguration.js.map +1 -0
- package/lib/Stripe/TerminalLocation.d.ts +215 -0
- package/lib/Stripe/TerminalLocation.d.ts.map +1 -0
- package/lib/Stripe/TerminalLocation.js +371 -0
- package/lib/Stripe/TerminalLocation.js.map +1 -0
- package/lib/Stripe/TerminalReader.d.ts +124 -0
- package/lib/Stripe/TerminalReader.d.ts.map +1 -0
- package/lib/Stripe/TerminalReader.js +239 -0
- package/lib/Stripe/TerminalReader.js.map +1 -0
- package/lib/Stripe/UpdateAccount.d.ts +23 -0
- package/lib/Stripe/UpdateAccount.d.ts.map +1 -0
- package/lib/Stripe/UpdateAccount.js +3 -0
- package/lib/Stripe/UpdateAccount.js.map +1 -0
- package/lib/Stripe/UpdateAccountHttp.d.ts +11 -0
- package/lib/Stripe/UpdateAccountHttp.d.ts.map +1 -0
- package/lib/Stripe/UpdateAccountHttp.js +18 -0
- package/lib/Stripe/UpdateAccountHttp.js.map +1 -0
- package/lib/Stripe/UpdateCreditGrant.d.ts +24 -0
- package/lib/Stripe/UpdateCreditGrant.d.ts.map +1 -0
- package/lib/Stripe/UpdateCreditGrant.js +3 -0
- package/lib/Stripe/UpdateCreditGrant.js.map +1 -0
- package/lib/Stripe/UpdateCreditGrantHttp.d.ts +11 -0
- package/lib/Stripe/UpdateCreditGrantHttp.d.ts.map +1 -0
- package/lib/Stripe/UpdateCreditGrantHttp.js +18 -0
- package/lib/Stripe/UpdateCreditGrantHttp.js.map +1 -0
- package/lib/Stripe/UpdateCustomer.d.ts +23 -0
- package/lib/Stripe/UpdateCustomer.d.ts.map +1 -0
- package/lib/Stripe/UpdateCustomer.js +3 -0
- package/lib/Stripe/UpdateCustomer.js.map +1 -0
- package/lib/Stripe/UpdateCustomerHttp.d.ts +11 -0
- package/lib/Stripe/UpdateCustomerHttp.d.ts.map +1 -0
- package/lib/Stripe/UpdateCustomerHttp.js +18 -0
- package/lib/Stripe/UpdateCustomerHttp.js.map +1 -0
- package/lib/Stripe/UpdateFileLink.d.ts +24 -0
- package/lib/Stripe/UpdateFileLink.d.ts.map +1 -0
- package/lib/Stripe/UpdateFileLink.js +3 -0
- package/lib/Stripe/UpdateFileLink.js.map +1 -0
- package/lib/Stripe/UpdateFileLinkHttp.d.ts +11 -0
- package/lib/Stripe/UpdateFileLinkHttp.d.ts.map +1 -0
- package/lib/Stripe/UpdateFileLinkHttp.js +18 -0
- package/lib/Stripe/UpdateFileLinkHttp.js.map +1 -0
- package/lib/Stripe/UpdateIssuingCard.d.ts +23 -0
- package/lib/Stripe/UpdateIssuingCard.d.ts.map +1 -0
- package/lib/Stripe/UpdateIssuingCard.js +3 -0
- package/lib/Stripe/UpdateIssuingCard.js.map +1 -0
- package/lib/Stripe/UpdateIssuingCardHttp.d.ts +11 -0
- package/lib/Stripe/UpdateIssuingCardHttp.d.ts.map +1 -0
- package/lib/Stripe/UpdateIssuingCardHttp.js +18 -0
- package/lib/Stripe/UpdateIssuingCardHttp.js.map +1 -0
- package/lib/Stripe/UpdateIssuingCardholder.d.ts +23 -0
- package/lib/Stripe/UpdateIssuingCardholder.d.ts.map +1 -0
- package/lib/Stripe/UpdateIssuingCardholder.js +3 -0
- package/lib/Stripe/UpdateIssuingCardholder.js.map +1 -0
- package/lib/Stripe/UpdateIssuingCardholderHttp.d.ts +11 -0
- package/lib/Stripe/UpdateIssuingCardholderHttp.d.ts.map +1 -0
- package/lib/Stripe/UpdateIssuingCardholderHttp.js +18 -0
- package/lib/Stripe/UpdateIssuingCardholderHttp.js.map +1 -0
- package/lib/Stripe/UpdateTaxSettings.d.ts +28 -0
- package/lib/Stripe/UpdateTaxSettings.d.ts.map +1 -0
- package/lib/Stripe/UpdateTaxSettings.js +3 -0
- package/lib/Stripe/UpdateTaxSettings.js.map +1 -0
- package/lib/Stripe/UpdateTaxSettingsHttp.d.ts +12 -0
- package/lib/Stripe/UpdateTaxSettingsHttp.d.ts.map +1 -0
- package/lib/Stripe/UpdateTaxSettingsHttp.js +26 -0
- package/lib/Stripe/UpdateTaxSettingsHttp.js.map +1 -0
- package/lib/Stripe/UpdateTerminalReader.d.ts +23 -0
- package/lib/Stripe/UpdateTerminalReader.d.ts.map +1 -0
- package/lib/Stripe/UpdateTerminalReader.js +3 -0
- package/lib/Stripe/UpdateTerminalReader.js.map +1 -0
- package/lib/Stripe/UpdateTerminalReaderHttp.d.ts +11 -0
- package/lib/Stripe/UpdateTerminalReaderHttp.d.ts.map +1 -0
- package/lib/Stripe/UpdateTerminalReaderHttp.js +18 -0
- package/lib/Stripe/UpdateTerminalReaderHttp.js.map +1 -0
- package/lib/Stripe/WebhookEndpoint.d.ts +135 -0
- package/lib/Stripe/WebhookEndpoint.d.ts.map +1 -0
- package/lib/Stripe/WebhookEndpoint.js +266 -0
- package/lib/Stripe/WebhookEndpoint.js.map +1 -0
- package/lib/Stripe/index.d.ts +151 -0
- package/lib/Stripe/index.d.ts.map +1 -0
- package/lib/Stripe/index.js +151 -0
- package/lib/Stripe/index.js.map +1 -0
- package/lib/Stripe/missing.d.ts +9 -0
- package/lib/Stripe/missing.d.ts.map +1 -0
- package/lib/Stripe/missing.js +13 -0
- package/lib/Stripe/missing.js.map +1 -0
- package/lib/Telemetry.d.ts +2 -61
- package/lib/Telemetry.d.ts.map +1 -1
- package/lib/Telemetry.js +3 -303
- package/lib/Telemetry.js.map +1 -1
- package/lib/TelemetryRuntime.d.ts +105 -0
- package/lib/TelemetryRuntime.d.ts.map +1 -0
- package/lib/TelemetryRuntime.js +308 -0
- package/lib/TelemetryRuntime.js.map +1 -0
- package/lib/Test/Alchemy.d.ts +2 -0
- package/lib/Test/Alchemy.d.ts.map +1 -1
- package/lib/Test/Alchemy.js +2 -0
- package/lib/Test/Alchemy.js.map +1 -1
- package/lib/Test/Bun.d.ts +2 -0
- package/lib/Test/Bun.d.ts.map +1 -1
- package/lib/Test/Bun.js +2 -0
- package/lib/Test/Bun.js.map +1 -1
- package/lib/Test/Core.d.ts +19 -1
- package/lib/Test/Core.d.ts.map +1 -1
- package/lib/Test/Core.js +19 -7
- package/lib/Test/Core.js.map +1 -1
- package/lib/Test/Vitest.d.ts +2 -0
- package/lib/Test/Vitest.d.ts.map +1 -1
- package/lib/Test/Vitest.js +2 -0
- package/lib/Test/Vitest.js.map +1 -1
- package/lib/Test/index.d.ts +1 -1
- package/lib/Test/index.d.ts.map +1 -1
- package/lib/Test/index.js +1 -1
- package/lib/Test/index.js.map +1 -1
- package/lib/Util/Node.d.ts +7 -0
- package/lib/Util/Node.d.ts.map +1 -1
- package/lib/Util/Node.js +7 -0
- package/lib/Util/Node.js.map +1 -1
- package/lib/Util/Terminal.d.ts.map +1 -1
- package/lib/Util/Terminal.js +1 -2
- package/lib/Util/Terminal.js.map +1 -1
- package/lib/Util/gitignore-rules-to-globs.d.ts +3 -3
- package/lib/Util/gitignore-rules-to-globs.js +3 -3
- package/lib/Util/proxy-chain.js +17 -0
- package/lib/Util/proxy-chain.js.map +1 -1
- package/lib/Util/zip.d.ts +2 -2
- package/lib/Util/zip.d.ts.map +1 -1
- package/lib/Util/zip.js +13 -38
- package/lib/Util/zip.js.map +1 -1
- package/lib/Utils/ip-address.d.ts +6 -0
- package/lib/Utils/ip-address.d.ts.map +1 -0
- package/lib/Utils/ip-address.js +83 -0
- package/lib/Utils/ip-address.js.map +1 -0
- package/lib/Website/Server.d.ts.map +1 -1
- package/lib/Website/Server.js +14 -4
- package/lib/Website/Server.js.map +1 -1
- package/lib/Website/ServerLocal.d.ts +2 -1
- package/lib/Website/ServerLocal.js +1 -2
- package/lib/Website/ServerLocal.js.map +1 -1
- package/lib/index.d.ts +0 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +0 -1
- package/lib/index.js.map +1 -1
- package/package.json +76 -44
- package/src/AWS/Bedrock/LanguageModel.ts +2 -2
- package/src/AWS/Budgets/BindingHttp.ts +2 -13
- package/src/AWS/Budgets/DescribeBudgetActionsForBudgetHttp.ts +0 -3
- package/src/AWS/CloudFront/KvRoutesUpdate.ts +20 -1
- package/src/AWS/Connection/DbAuthToken.ts +1 -1
- package/src/AWS/Credentials.ts +3 -3
- package/src/AWS/DSQL/Connect.ts +2 -2
- package/src/AWS/DynamoDB/Table.ts +33 -17
- package/src/AWS/EC2/Instance.ts +12 -1
- package/src/AWS/EC2/SecurityGroup.ts +376 -79
- package/src/AWS/EC2/SecurityGroupRule.ts +147 -23
- package/src/AWS/ECR/Image.ts +29 -7
- package/src/AWS/ECS/FlociServiceProvider.ts +2 -2
- package/src/AWS/ECS/FlociTaskProvider.ts +2 -2
- package/src/AWS/ECS/Service.ts +6 -7
- package/src/AWS/EKS/KubernetesAdapter.ts +4 -4
- package/src/AWS/Environment.ts +6 -6
- package/src/AWS/Lambda/BindingHttp.ts +237 -25
- package/src/AWS/Lambda/FlociFunctionProvider.ts +2 -2
- package/src/AWS/Lambda/FlociMicrovmImageProvider.ts +2 -2
- package/src/AWS/Lambda/Function.ts +36 -16
- package/src/AWS/Lambda/MicrovmBinding.ts +15 -276
- package/src/AWS/Lambda/MicrovmBundle.ts +1 -16
- package/src/AWS/Lambda/MicrovmRuntimeContext.ts +1 -1
- package/src/AWS/Local/DevWatchProvider.ts +8 -7
- package/src/AWS/Local/Local.ts +11 -10
- package/src/AWS/Logs/LogGroup.ts +8 -2
- package/src/AWS/Organizations/common.ts +4 -1
- package/src/AWS/RDS/Connect.ts +3 -3
- package/src/AWS/RDS/DBInstance.ts +979 -53
- package/src/AWS/RDS/DBParameterGroup.ts +89 -40
- package/src/AWS/S3/BindingHttp.ts +46 -37
- package/src/AWS/S3/Bucket.ts +220 -82
- package/src/AWS/S3/PresignGetObject.ts +2 -4
- package/src/AWS/S3/PresignPutObject.ts +2 -4
- package/src/AWS/SNS/Subscription.ts +29 -9
- package/src/AWS/StateStore/State.ts +24 -36
- package/src/AWS/Synthetics/Canary.ts +4 -11
- package/src/Alchemist/Entrypoint.ts +33 -0
- package/src/Alchemist/Session.ts +9 -17
- package/src/Alchemist/routes/nuke.ts +1 -1
- package/src/Alchemist/routes/state.ts +15 -2
- package/src/Auth/AuthProvider.ts +1 -1
- package/src/Auth/Demand.ts +1 -1
- package/src/Auth/Env.ts +4 -4
- package/src/Auth/Lock.ts +22 -19
- package/src/Auth/Profile.ts +1 -1
- package/src/Auth/Resolve.ts +1 -1
- package/src/Cli/LoggingCli.ts +1 -1
- package/src/Cli/commands/aws.ts +2 -2
- package/src/Cli/commands/cloudflare.ts +10 -10
- package/src/Cli/commands/deploy.ts +3 -3
- package/src/Cli/commands/dev.ts +6 -3
- package/src/Cli/commands/drift.ts +1 -1
- package/src/Cli/commands/flags.ts +20 -16
- package/src/Cli/commands/instrument.ts +9 -0
- package/src/Cli/commands/logs.ts +4 -4
- package/src/Cli/commands/nuke.ts +9 -9
- package/src/Cli/commands/profile/commands.ts +8 -8
- package/src/Cli/commands/provider.ts +1 -1
- package/src/Cli/commands/state.ts +5 -5
- package/src/Cli/components/ui/Data.tsx +1 -1
- package/src/Cli/components/ui/Environment.tsx +3 -2
- package/src/Cli/components/ui/Feedback.tsx +2 -2
- package/src/Cli/components/ui/Interactive.tsx +4 -5
- package/src/Cli/components/ui/Layout.tsx +8 -8
- package/src/Cli/components/ui/Live.tsx +2 -2
- package/src/Cli/components/ui/ProgressBar.tsx +1 -1
- package/src/Cli/components/ui/Transcript.tsx +1 -1
- package/src/Cli/components/ui/Typography.tsx +1 -1
- package/src/Cli/components/view/ApprovePlan.tsx +3 -2
- package/src/Cli/components/view/Help.tsx +1 -1
- package/src/Cli/components/view/Logo.tsx +3 -2
- package/src/Cli/components/view/Nuke.tsx +1 -1
- package/src/Cli/components/view/PlanDecision.tsx +3 -2
- package/src/Cli/components/view/PlanRow.tsx +1 -1
- package/src/Cli/components/view/PlanView.tsx +3 -2
- package/src/Cli/components/view/Profile.tsx +1 -1
- package/src/Cli/components/view/ProfileDashboard.tsx +3 -2
- package/src/Cli/components/view/Prompts.tsx +3 -2
- package/src/Cli/components/view/Runtime.tsx +4 -3
- package/src/Cli/components/view/SigilCli.tsx +1 -1
- package/src/Cli/components/view/StackOutputs.tsx +1 -1
- package/src/Cli/components/view/StateExplorer.tsx +3 -3
- package/src/Cli/components/view/usePlanPresentation.ts +1 -1
- package/src/Cli/components/view/usePlanViewport.ts +1 -1
- package/src/Cli/exec.ts +5 -2
- package/src/Cli/main.ts +6 -7
- package/src/Cloudflare/AI/GatewayProvider.ts +1 -1
- package/src/Cloudflare/AI/LanguageModel.ts +2 -2
- package/src/Cloudflare/AI/ProviderKey.ts +3 -3
- package/src/Cloudflare/AI/SearchToken.ts +3 -6
- package/src/Cloudflare/Access.ts +1 -1
- package/src/Cloudflare/Alerting/Webhook.ts +1 -1
- package/src/Cloudflare/Bridge.ts +9 -0
- package/src/Cloudflare/CloudflareEnvironment.ts +4 -8
- package/src/Cloudflare/CloudflareEnvironmentService.ts +10 -0
- package/src/Cloudflare/Containers/ContainerApplication.ts +10 -3
- package/src/Cloudflare/Containers/ContainerPlatform.ts +6 -6
- package/src/Cloudflare/Containers/ContainerProvider.ts +183 -86
- package/src/Cloudflare/Containers/ContainerPublication.ts +13 -0
- package/src/Cloudflare/Containers/LocalContainerProvider.ts +3 -2
- package/src/Cloudflare/D1/Database.ts +3 -3
- package/src/Cloudflare/Fetcher.ts +65 -174
- package/src/Cloudflare/Flagship/Flag.ts +13 -2
- package/src/Cloudflare/HostnameTlsSetting/HostnameTlsSetting.ts +21 -41
- package/src/Cloudflare/Hyperdrive/Connection.ts +19 -12
- package/src/Cloudflare/Iam/ResourceGroup.ts +1 -1
- package/src/Cloudflare/LoadBalancer/LoadBalancer.ts +2 -2
- package/src/Cloudflare/LoadBalancer/Monitor.ts +1 -1
- package/src/Cloudflare/Local.ts +8 -4
- package/src/Cloudflare/LocalRuntime.ts +8 -2
- package/src/Cloudflare/Logs.ts +57 -49
- package/src/Cloudflare/MagicTransit/IpsecTunnel.ts +1 -1
- package/src/Cloudflare/MtlsCertificate/MtlsCertificate.ts +1 -1
- package/src/Cloudflare/Organization/Organization.ts +1 -1
- package/src/Cloudflare/OriginTlsClientAuth/Certificate.ts +2 -2
- package/src/Cloudflare/OriginTlsClientAuth/HostnameAssociation.ts +1 -1
- package/src/Cloudflare/OriginTlsClientAuth/HostnameCertificate.ts +2 -2
- package/src/Cloudflare/OriginTlsClientAuth/Setting.ts +1 -1
- package/src/Cloudflare/Pipelines/LegacyPipeline.ts +2 -2
- package/src/Cloudflare/Pipelines/Sink.ts +3 -3
- package/src/Cloudflare/Providers.ts +11 -49
- package/src/Cloudflare/Queues/Consumer.ts +2 -2
- package/src/Cloudflare/Queues/Queue.ts +2 -2
- package/src/Cloudflare/R2/Bucket.ts +25 -2
- package/src/Cloudflare/R2/BucketBinding.ts +1 -0
- package/src/Cloudflare/R2/BucketSippy.ts +7 -7
- package/src/Cloudflare/R2/BucketTypes.ts +8 -0
- package/src/Cloudflare/R2/WriteBucketBinding.ts +9 -6
- package/src/Cloudflare/R2/index.ts +1 -0
- package/src/Cloudflare/SecretsStore/Secret.ts +3 -3
- package/src/Cloudflare/Snippets/SnippetRules.ts +9 -3
- package/src/Cloudflare/StateStore/State.ts +15 -16
- package/src/Cloudflare/Website/Nuxt.ts +1 -1
- package/src/Cloudflare/Website/Octane.ts +1 -1
- package/src/Cloudflare/Website/SvelteKit.ts +1 -1
- package/src/Cloudflare/Workers/Assets.ts +1 -1
- package/src/Cloudflare/Workers/CloudflareTracer.ts +1 -1
- package/src/Cloudflare/Workers/DurableObject.ts +40 -8
- package/src/Cloudflare/Workers/DurableObjectBridge.ts +1 -1
- package/src/Cloudflare/Workers/DurableObjectState.ts +1 -1
- package/src/Cloudflare/Workers/DurableObjectStorage.ts +22 -24
- package/src/Cloudflare/Workers/HttpServer.ts +2 -1
- package/src/Cloudflare/Workers/InferEnv.ts +2 -2
- package/src/Cloudflare/Workers/LocalWorkerProvider.ts +35 -24
- package/src/Cloudflare/Workers/Rpc.ts +17 -2
- package/src/Cloudflare/Workers/RpcAsync.ts +1 -1
- package/src/Cloudflare/Workers/Sources/Prebuilt.ts +3 -2
- package/src/Cloudflare/Workers/Sources/Python.ts +3 -2
- package/src/Cloudflare/Workers/Sources/Rolldown.ts +34 -18
- package/src/Cloudflare/Workers/Sources/WorkerModulePlugin.ts +75 -0
- package/src/Cloudflare/Workers/ViteChild.shared.ts +1 -0
- package/src/Cloudflare/Workers/ViteChild.ts +2 -3
- package/src/Cloudflare/Workers/Worker.ts +176 -218
- package/src/Cloudflare/Workers/WorkerBinding.ts +1 -1
- package/src/Cloudflare/Workers/WorkerBridge.ts +6 -6
- package/src/Cloudflare/Workers/WorkerEntrypoint.ts +47 -14
- package/src/Cloudflare/Workers/WorkerProvider.ts +577 -30
- package/src/Cloudflare/Workers/WorkerRuntime.ts +195 -0
- package/src/Cloudflare/Workers/WorkerRuntimeContext.ts +10 -6
- package/src/Cloudflare/Workers/worker-module.d.ts +9 -0
- package/src/Cloudflare/Workflows/Workflow.ts +7 -50
- package/src/Cloudflare/Workflows/WorkflowBridge.ts +9 -7
- package/src/Cloudflare/Workflows/WorkflowRuntime.ts +56 -0
- package/src/Cloudflare/index.ts +3 -1
- package/src/Command/Dev.ts +2 -1
- package/src/Command/Local.ts +8 -2
- package/src/Command/Memo.ts +6 -7
- package/src/Docker/Container.ts +1 -1
- package/src/Docker/Docker.ts +225 -85
- package/src/Docker/Image.ts +1 -1
- package/src/Docker/Registry.ts +1 -1
- package/src/Docker/RegistryError.ts +52 -0
- package/src/Docker/RemoteImage.ts +1 -1
- package/src/Docker/index.ts +5 -0
- package/src/Drizzle/Postgres.ts +3 -1
- package/src/Fly/BucketBinding.ts +6 -6
- package/src/Fly/GetSecretHttp.ts +1 -1
- package/src/Fly/RedisBinding.ts +2 -2
- package/src/Fly/Secret.ts +4 -4
- package/src/Fly/SecretHttp.ts +1 -1
- package/src/Fly/Service.ts +3 -3
- package/src/Fly/Sprite.ts +2 -2
- package/src/Fly/Website/AssetDeployment.ts +12 -9
- package/src/Fly/replicas.ts +47 -9
- package/src/Git/Api/GitHub.ts +106 -0
- package/src/Git/Api/Internal.ts +27 -0
- package/src/Git/Api/Objects.ts +161 -0
- package/src/Git/Api/Protocol.ts +37 -0
- package/src/Git/Api/Pulls.ts +158 -0
- package/src/Git/Api/Refs.ts +96 -0
- package/src/Git/Api/Repos.ts +170 -0
- package/src/Git/Api/Schema.ts +552 -0
- package/src/Git/Api.ts +82 -0
- package/src/Git/BlobStore.ts +265 -0
- package/src/Git/BlobStoreS3.ts +265 -0
- package/src/Git/DESIGN.md +2098 -0
- package/src/Git/Engine.ts +461 -0
- package/src/Git/GitHubCompat.ts +713 -0
- package/src/Git/Hasher/Hasher.ts +360 -0
- package/src/Git/Hasher/Lambda.ts +126 -0
- package/src/Git/Hasher/LambdaEvent.ts +149 -0
- package/src/Git/Hasher/LambdaFunction.ts +46 -0
- package/src/Git/Hasher/Protocol.ts +309 -0
- package/src/Git/Hasher/WorkerLoader.ts +179 -0
- package/src/Git/Hasher/WorkerLoaderModule.ts +72 -0
- package/src/Git/Hasher/index.ts +39 -0
- package/src/Git/Http/ReceivePack.ts +133 -0
- package/src/Git/Http.ts +4 -0
- package/src/Git/Jobs/Bundle.ts +264 -0
- package/src/Git/Jobs/Compact.ts +517 -0
- package/src/Git/Jobs/Fork.ts +376 -0
- package/src/Git/Jobs/Import.ts +435 -0
- package/src/Git/Jobs/Purge.ts +136 -0
- package/src/Git/Operations.ts +1087 -0
- package/src/Git/Protocol/Advertise.ts +159 -0
- package/src/Git/Protocol/Delta.ts +182 -0
- package/src/Git/Protocol/GzipBody.ts +153 -0
- package/src/Git/Protocol/ObjectCodec.ts +941 -0
- package/src/Git/Protocol/PackParser.ts +907 -0
- package/src/Git/Protocol/PackWriter.ts +141 -0
- package/src/Git/Protocol/PartialScan.ts +705 -0
- package/src/Git/Protocol/Pkt.ts +289 -0
- package/src/Git/Protocol/ReceivePack.ts +446 -0
- package/src/Git/Protocol/Sideband.ts +289 -0
- package/src/Git/Protocol/Store.ts +176 -0
- package/src/Git/Protocol/TreeDiff.ts +464 -0
- package/src/Git/Protocol/UploadPack.ts +366 -0
- package/src/Git/Protocol/Zlib.ts +350 -0
- package/src/Git/Push.ts +71 -0
- package/src/Git/PushInput.ts +73 -0
- package/src/Git/PushWire.ts +90 -0
- package/src/Git/RFC-building-blocks.md +548 -0
- package/src/Git/RegistryD1.ts +338 -0
- package/src/Git/RegistryObject.ts +522 -0
- package/src/Git/RepoObject.ts +5876 -0
- package/src/Git/Server.ts +827 -0
- package/src/Git/Store/Closure.ts +539 -0
- package/src/Git/Store/HeadSnapshot.ts +49 -0
- package/src/Git/Store/IncomingBody.ts +67 -0
- package/src/Git/Store/Keys.ts +129 -0
- package/src/Git/Store/ObjectStore.ts +1086 -0
- package/src/Git/Store/PackSource.ts +160 -0
- package/src/Git/Store/Sql.ts +492 -0
- package/src/Git/Store/StreamingSource.ts +335 -0
- package/src/Git/index.ts +75 -0
- package/src/GitHub/BranchProtection.ts +651 -0
- package/src/GitHub/Collaborator.ts +239 -0
- package/src/GitHub/Env.ts +8 -8
- package/src/GitHub/Issue.ts +379 -0
- package/src/GitHub/Label.ts +373 -0
- package/src/GitHub/Milestone.ts +424 -0
- package/src/GitHub/Providers.ts +34 -2
- package/src/GitHub/PullRequest.ts +570 -0
- package/src/GitHub/Release.ts +520 -0
- package/src/GitHub/Ruleset.ts +568 -0
- package/src/GitHub/TeamAccess.ts +251 -0
- package/src/GitHub/WikiPage.ts +581 -0
- package/src/GitHub/index.ts +10 -0
- package/src/Hetzner/Server.ts +34 -6
- package/src/Http/Platform.ts +47 -0
- package/src/Http/index.ts +5 -0
- package/src/Http.ts +9 -5
- package/src/Kubernetes/internal/helm.ts +1 -1
- package/src/Kubernetes/internal/kubeconfig.ts +1 -1
- package/src/Kubernetes/internal/workload.ts +4 -4
- package/src/Local/LocalProvider.ts +4 -3
- package/src/Local/ProviderLayer.ts +31 -15
- package/src/Local/RpcProvider.ts +3 -3
- package/src/Local/RpcProviderProxy.ts +28 -21
- package/src/Local/RpcServer.ts +90 -53
- package/src/Local/RpcServerEnvironment.ts +1 -1
- package/src/Local/RpcSpawner.ts +1 -1
- package/src/Local/Sidecar.ts +32 -0
- package/src/Nuke.ts +27 -23
- package/src/Output.ts +1 -1
- package/src/Phase.ts +3 -3
- package/src/Plan.ts +11 -4
- package/src/Planetscale/Credentials.ts +1 -1
- package/src/Prisma/App.ts +126 -80
- package/src/Prisma/Branch.ts +133 -66
- package/src/Prisma/Bucket.ts +64 -25
- package/src/Prisma/BucketAccessKey.ts +68 -32
- package/src/Prisma/Client.ts +8 -11
- package/src/Prisma/Compute.ts +355 -179
- package/src/Prisma/ComputeArchive.ts +29 -3
- package/src/Prisma/ComputeBuild.ts +256 -3
- package/src/Prisma/ComputeLifecycle.ts +179 -160
- package/src/Prisma/Connection.ts +112 -55
- package/src/Prisma/Credentials.ts +73 -0
- package/src/Prisma/Database.ts +191 -155
- package/src/Prisma/Deployment.ts +70 -50
- package/src/Prisma/EnvironmentVariable.ts +112 -69
- package/src/Prisma/Internal/AppPromotion.ts +39 -27
- package/src/Prisma/Internal/DatabaseSecrets.ts +23 -19
- package/src/Prisma/Internal/DeploymentActions.ts +24 -40
- package/src/Prisma/Internal/DeploymentIdentity.ts +29 -3
- package/src/Prisma/Internal/DeploymentObserve.ts +4 -5
- package/src/Prisma/Internal/LogsClient.ts +165 -0
- package/src/Prisma/Internal/Observed.ts +192 -0
- package/src/Prisma/Internal/Pagination.ts +16 -0
- package/src/Prisma/Operations.ts +3 -2
- package/src/Prisma/PrismaEnvironment.ts +2 -2
- package/src/Prisma/PrismaLogs.ts +38 -16
- package/src/Prisma/Project.ts +163 -129
- package/src/Prisma/Providers.ts +37 -2
- package/src/Prisma/SourceRepository.ts +223 -87
- package/src/Provider.ts +19 -15
- package/src/Railway/AuditLog.ts +41 -17
- package/src/Railway/AuthProvider.ts +1 -1
- package/src/Railway/Bucket.ts +94 -63
- package/src/Railway/BucketBinding.ts +7 -7
- package/src/Railway/Catalog.ts +8 -1
- package/src/Railway/CloudAgent.ts +71 -54
- package/src/Railway/CustomDomain.ts +109 -64
- package/src/Railway/Environment.ts +18 -7
- package/src/Railway/Function.ts +165 -132
- package/src/Railway/GraphQL.ts +215 -0
- package/src/Railway/Group.ts +171 -71
- package/src/Railway/LoginSession.ts +7 -12
- package/src/Railway/Mongo.ts +227 -185
- package/src/Railway/MountVolume.ts +5 -4
- package/src/Railway/MySQL.ts +227 -185
- package/src/Railway/Postgres.ts +234 -188
- package/src/Railway/PrivateNetwork.ts +444 -310
- package/src/Railway/Project.ts +83 -61
- package/src/Railway/ProjectEnvironment.ts +84 -55
- package/src/Railway/Providers.ts +6 -2
- package/src/Railway/Redis.ts +114 -89
- package/src/Railway/RedisBinding.ts +2 -2
- package/src/Railway/Sandbox.ts +279 -130
- package/src/Railway/SandboxCheckpoint.ts +290 -0
- package/src/Railway/Service.ts +4 -1
- package/src/Railway/ServiceDomain.ts +77 -87
- package/src/Railway/ServiceProvider.ts +274 -159
- package/src/Railway/TcpProxy.ts +48 -35
- package/src/Railway/Template.ts +184 -130
- package/src/Railway/Usage.ts +91 -45
- package/src/Railway/Variable.ts +33 -33
- package/src/Railway/Volume.ts +148 -88
- package/src/Railway/VolumeBackup.ts +140 -97
- package/src/Railway/Website/Cdn.ts +136 -55
- package/src/Railway/hosted.ts +10 -3
- package/src/Railway/index.ts +1 -0
- package/src/Railway/transient.ts +26 -52
- package/src/Rpc.ts +53 -1
- package/src/Runtime/Bootstrap/Process.ts +2 -2
- package/src/Runtime.ts +1 -1
- package/src/RuntimeContext.ts +1 -1
- package/src/SQL/Postgres.ts +5 -1
- package/src/SQL/PostgresTls.ts +70 -0
- package/src/Server/Process.ts +1 -1
- package/src/Server/index.ts +0 -2
- package/src/Stack.ts +3 -2
- package/src/StackContext.ts +6 -0
- package/src/State/HttpStateStore.ts +18 -31
- package/src/State/PostgresState.ts +6 -5
- package/src/State/State.ts +5 -0
- package/src/Stripe/Account.ts +795 -0
- package/src/Stripe/AccountExternalAccount.ts +568 -0
- package/src/Stripe/AccountPerson.ts +562 -0
- package/src/Stripe/Alert.ts +437 -0
- package/src/Stripe/ApplePayDomain.ts +254 -0
- package/src/Stripe/AppsSecret.ts +385 -0
- package/src/Stripe/AuthProvider.ts +74 -0
- package/src/Stripe/BillingMeter.ts +449 -0
- package/src/Stripe/BillingPortalConfiguration.ts +920 -0
- package/src/Stripe/ConsumeEvents.ts +278 -0
- package/src/Stripe/Coupon.ts +535 -0
- package/src/Stripe/CreateAccount.ts +39 -0
- package/src/Stripe/CreateAccountHttp.ts +20 -0
- package/src/Stripe/CreateAccountLink.ts +43 -0
- package/src/Stripe/CreateAccountLinkHttp.ts +20 -0
- package/src/Stripe/CreateAppsSecret.ts +39 -0
- package/src/Stripe/CreateAppsSecretHttp.ts +20 -0
- package/src/Stripe/CreateBillingPortalSession.ts +52 -0
- package/src/Stripe/CreateBillingPortalSessionHttp.ts +20 -0
- package/src/Stripe/CreateCheckoutSession.ts +53 -0
- package/src/Stripe/CreateCheckoutSessionHttp.ts +20 -0
- package/src/Stripe/CreateCreditGrant.ts +45 -0
- package/src/Stripe/CreateCreditGrantHttp.ts +20 -0
- package/src/Stripe/CreateCustomer.ts +38 -0
- package/src/Stripe/CreateCustomerHttp.ts +20 -0
- package/src/Stripe/CreateFileLink.ts +37 -0
- package/src/Stripe/CreateFileLinkHttp.ts +20 -0
- package/src/Stripe/CreateIssuingCard.ts +43 -0
- package/src/Stripe/CreateIssuingCardHttp.ts +20 -0
- package/src/Stripe/CreateIssuingCardholder.ts +50 -0
- package/src/Stripe/CreateIssuingCardholderHttp.ts +20 -0
- package/src/Stripe/CreateTerminalReader.ts +43 -0
- package/src/Stripe/CreateTerminalReaderHttp.ts +20 -0
- package/src/Stripe/Credentials.ts +54 -0
- package/src/Stripe/CreditGrant.ts +627 -0
- package/src/Stripe/Customer.ts +315 -0
- package/src/Stripe/CustomerTaxId.ts +351 -0
- package/src/Stripe/EntitlementsFeature.ts +384 -0
- package/src/Stripe/Events.ts +94 -0
- package/src/Stripe/FileLink.ts +335 -0
- package/src/Stripe/IssuingCard.ts +712 -0
- package/src/Stripe/IssuingCardholder.ts +907 -0
- package/src/Stripe/IssuingPersonalizationDesign.ts +582 -0
- package/src/Stripe/Metadata.ts +93 -0
- package/src/Stripe/PaymentLink.ts +779 -0
- package/src/Stripe/PaymentMethodConfiguration.ts +619 -0
- package/src/Stripe/PaymentMethodDomain.ts +342 -0
- package/src/Stripe/Plan.ts +482 -0
- package/src/Stripe/Price.ts +523 -0
- package/src/Stripe/Product.ts +339 -0
- package/src/Stripe/ProductFeature.ts +300 -0
- package/src/Stripe/PromotionCode.ts +612 -0
- package/src/Stripe/Providers.ts +306 -0
- package/src/Stripe/RadarValueList.ts +397 -0
- package/src/Stripe/RadarValueListItem.ts +308 -0
- package/src/Stripe/RestrictedApiKey.ts +210 -0
- package/src/Stripe/RetrieveAccount.ts +42 -0
- package/src/Stripe/RetrieveAccountExternalAccount.ts +47 -0
- package/src/Stripe/RetrieveAccountExternalAccountHttp.ts +52 -0
- package/src/Stripe/RetrieveAccountHttp.ts +21 -0
- package/src/Stripe/RetrieveAccountPerson.ts +42 -0
- package/src/Stripe/RetrieveAccountPersonHttp.ts +52 -0
- package/src/Stripe/RetrieveAlert.ts +42 -0
- package/src/Stripe/RetrieveAlertHttp.ts +20 -0
- package/src/Stripe/RetrieveApplePayDomain.ts +46 -0
- package/src/Stripe/RetrieveApplePayDomainHttp.ts +21 -0
- package/src/Stripe/RetrieveAppsSecret.ts +47 -0
- package/src/Stripe/RetrieveAppsSecretHttp.ts +58 -0
- package/src/Stripe/RetrieveBillingMeter.ts +42 -0
- package/src/Stripe/RetrieveBillingMeterHttp.ts +20 -0
- package/src/Stripe/RetrieveBillingPortalConfiguration.ts +47 -0
- package/src/Stripe/RetrieveBillingPortalConfigurationHttp.ts +20 -0
- package/src/Stripe/RetrieveCoupon.ts +42 -0
- package/src/Stripe/RetrieveCouponHttp.ts +21 -0
- package/src/Stripe/RetrieveCreditGrant.ts +46 -0
- package/src/Stripe/RetrieveCreditGrantHttp.ts +21 -0
- package/src/Stripe/RetrieveCustomer.ts +42 -0
- package/src/Stripe/RetrieveCustomerHttp.ts +21 -0
- package/src/Stripe/RetrieveCustomerTaxId.ts +42 -0
- package/src/Stripe/RetrieveCustomerTaxIdHttp.ts +52 -0
- package/src/Stripe/RetrieveEntitlementsFeature.ts +47 -0
- package/src/Stripe/RetrieveEntitlementsFeatureHttp.ts +20 -0
- package/src/Stripe/RetrieveFileLink.ts +42 -0
- package/src/Stripe/RetrieveFileLinkHttp.ts +21 -0
- package/src/Stripe/RetrieveIssuingCard.ts +42 -0
- package/src/Stripe/RetrieveIssuingCardHttp.ts +21 -0
- package/src/Stripe/RetrieveIssuingCardholder.ts +47 -0
- package/src/Stripe/RetrieveIssuingCardholderHttp.ts +21 -0
- package/src/Stripe/RetrieveIssuingPersonalizationDesign.ts +47 -0
- package/src/Stripe/RetrieveIssuingPersonalizationDesignHttp.ts +21 -0
- package/src/Stripe/RetrievePaymentLink.ts +42 -0
- package/src/Stripe/RetrievePaymentLinkHttp.ts +21 -0
- package/src/Stripe/RetrievePaymentMethodConfiguration.ts +47 -0
- package/src/Stripe/RetrievePaymentMethodConfigurationHttp.ts +20 -0
- package/src/Stripe/RetrievePaymentMethodDomain.ts +47 -0
- package/src/Stripe/RetrievePaymentMethodDomainHttp.ts +20 -0
- package/src/Stripe/RetrievePlan.ts +39 -0
- package/src/Stripe/RetrievePlanHttp.ts +21 -0
- package/src/Stripe/RetrievePrice.ts +39 -0
- package/src/Stripe/RetrievePriceHttp.ts +21 -0
- package/src/Stripe/RetrieveProduct.ts +46 -0
- package/src/Stripe/RetrieveProductFeature.ts +46 -0
- package/src/Stripe/RetrieveProductFeatureHttp.ts +52 -0
- package/src/Stripe/RetrieveProductHttp.ts +58 -0
- package/src/Stripe/RetrievePromotionCode.ts +46 -0
- package/src/Stripe/RetrievePromotionCodeHttp.ts +21 -0
- package/src/Stripe/RetrieveRadarValueList.ts +46 -0
- package/src/Stripe/RetrieveRadarValueListHttp.ts +20 -0
- package/src/Stripe/RetrieveRadarValueListItem.ts +47 -0
- package/src/Stripe/RetrieveRadarValueListItemHttp.ts +20 -0
- package/src/Stripe/RetrieveShippingRate.ts +42 -0
- package/src/Stripe/RetrieveShippingRateHttp.ts +21 -0
- package/src/Stripe/RetrieveTaxRate.ts +42 -0
- package/src/Stripe/RetrieveTaxRateHttp.ts +21 -0
- package/src/Stripe/RetrieveTaxRegistration.ts +46 -0
- package/src/Stripe/RetrieveTaxRegistrationHttp.ts +21 -0
- package/src/Stripe/RetrieveTaxSettings.ts +41 -0
- package/src/Stripe/RetrieveTaxSettingsHttp.ts +46 -0
- package/src/Stripe/RetrieveTerminalConfiguration.ts +47 -0
- package/src/Stripe/RetrieveTerminalConfigurationHttp.ts +21 -0
- package/src/Stripe/RetrieveTerminalLocation.ts +45 -0
- package/src/Stripe/RetrieveTerminalLocationHttp.ts +21 -0
- package/src/Stripe/RetrieveTerminalReader.ts +46 -0
- package/src/Stripe/RetrieveTerminalReaderHttp.ts +21 -0
- package/src/Stripe/RetrieveWebhookEndpoint.ts +46 -0
- package/src/Stripe/RetrieveWebhookEndpointHttp.ts +21 -0
- package/src/Stripe/ShippingRate.ts +614 -0
- package/src/Stripe/StripeHttp.ts +241 -0
- package/src/Stripe/TaxRate.ts +468 -0
- package/src/Stripe/TaxRegistration.ts +722 -0
- package/src/Stripe/TaxSettings.ts +395 -0
- package/src/Stripe/TerminalConfiguration.ts +977 -0
- package/src/Stripe/TerminalLocation.ts +627 -0
- package/src/Stripe/TerminalReader.ts +377 -0
- package/src/Stripe/UpdateAccount.ts +42 -0
- package/src/Stripe/UpdateAccountHttp.ts +21 -0
- package/src/Stripe/UpdateCreditGrant.ts +47 -0
- package/src/Stripe/UpdateCreditGrantHttp.ts +21 -0
- package/src/Stripe/UpdateCustomer.ts +42 -0
- package/src/Stripe/UpdateCustomerHttp.ts +21 -0
- package/src/Stripe/UpdateFileLink.ts +43 -0
- package/src/Stripe/UpdateFileLinkHttp.ts +21 -0
- package/src/Stripe/UpdateIssuingCard.ts +46 -0
- package/src/Stripe/UpdateIssuingCardHttp.ts +21 -0
- package/src/Stripe/UpdateIssuingCardholder.ts +46 -0
- package/src/Stripe/UpdateIssuingCardholderHttp.ts +21 -0
- package/src/Stripe/UpdateTaxSettings.ts +48 -0
- package/src/Stripe/UpdateTaxSettingsHttp.ts +46 -0
- package/src/Stripe/UpdateTerminalReader.ts +46 -0
- package/src/Stripe/UpdateTerminalReaderHttp.ts +21 -0
- package/src/Stripe/WebhookEndpoint.ts +411 -0
- package/src/Stripe/index.ts +150 -0
- package/src/Stripe/missing.ts +16 -0
- package/src/Telemetry.ts +15 -439
- package/src/TelemetryRuntime.ts +446 -0
- package/src/Test/Alchemy.ts +2 -0
- package/src/Test/Bun.ts +2 -0
- package/src/Test/Core.ts +32 -9
- package/src/Test/Vitest.ts +2 -0
- package/src/Test/index.ts +6 -1
- package/src/Util/Node.ts +9 -0
- package/src/Util/Terminal.ts +1 -1
- package/src/Util/gitignore-rules-to-globs.ts +3 -3
- package/src/Util/proxy-chain.ts +19 -0
- package/src/Util/zip.ts +16 -45
- package/src/Utils/ip-address.ts +90 -0
- package/src/Website/Server.ts +19 -4
- package/src/Website/ServerLocal.ts +6 -2
- package/src/index.ts +0 -1
- package/lib/AWS/Website/ServerLocal.d.ts +0 -2
- package/lib/AWS/Website/ServerLocal.d.ts.map +0 -1
- package/lib/AWS/Website/ServerLocal.js +0 -4
- package/lib/AWS/Website/ServerLocal.js.map +0 -1
- package/lib/Railway/RetryPolicy.d.ts +0 -22
- package/lib/Railway/RetryPolicy.d.ts.map +0 -1
- package/lib/Railway/RetryPolicy.js +0 -43
- package/lib/Railway/RetryPolicy.js.map +0 -1
- package/src/AWS/Website/ServerLocal.ts +0 -4
- package/src/Railway/RetryPolicy.ts +0 -53
|
@@ -0,0 +1,3839 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The per-repo Durable Object (DESIGN.md §2, §3.4, §3.6, §8).
|
|
3
|
+
*
|
|
4
|
+
* One DO per repo, addressed by `getByName(repoId)` (a ULID — never
|
|
5
|
+
* `owner/name`, so renames never move data). The DO owns refs, the object
|
|
6
|
+
* index and loose bytes, tokens, the commit graph, push staging, and the
|
|
7
|
+
* alarm jobs (import / fork / delete-purge / staging-GC). It runs the git
|
|
8
|
+
* v0 wire protocol in its `fetch` handler — advertisement, upload-pack,
|
|
9
|
+
* receive-pack — because every byte those need lives in this DO's SQLite.
|
|
10
|
+
*
|
|
11
|
+
* NOTE: the protocol *choreography* (advertisement builder, request
|
|
12
|
+
* parsers, pack writer/parser) is implemented in this file against the
|
|
13
|
+
* pure codec primitives in `src/Git/Protocol/` (`Pkt`, `Sideband`, `ObjectCodec`,
|
|
14
|
+
* `Delta`, `Zlib`, `Store`). DESIGN.md places these in
|
|
15
|
+
* `src/git/{Advertise,UploadPack,ReceivePack,PackParser,PackWriter}.ts`;
|
|
16
|
+
* they live here (exported) until the git-layer split lands — moving them
|
|
17
|
+
* is a mechanical extraction.
|
|
18
|
+
*
|
|
19
|
+
* ### Wire endpoints
|
|
20
|
+
* The Worker proxies these untouched to `stub.fetch`:
|
|
21
|
+
* **Example:** Routes served by this DO's fetch handler
|
|
22
|
+
* ```
|
|
23
|
+
* GET /:owner/:repo[.git]/info/refs?service=git-(upload|receive)-pack
|
|
24
|
+
* POST /:owner/:repo[.git]/git-upload-pack
|
|
25
|
+
* POST /:owner/:repo[.git]/git-receive-pack
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
import * as Cloudflare from "../Cloudflare/index.js";
|
|
29
|
+
import { RuntimeContext } from "../RuntimeContext.js";
|
|
30
|
+
import * as Context from "effect/Context";
|
|
31
|
+
import * as Effect from "effect/Effect";
|
|
32
|
+
import * as Fiber from "effect/Fiber";
|
|
33
|
+
import * as Option from "effect/Option";
|
|
34
|
+
import * as Redacted from "effect/Redacted";
|
|
35
|
+
import * as Result from "effect/Result";
|
|
36
|
+
import * as Schema from "effect/Schema";
|
|
37
|
+
import * as Semaphore from "effect/Semaphore";
|
|
38
|
+
import * as Stream from "effect/Stream";
|
|
39
|
+
import * as FetchHttpClient from "effect/unstable/http/FetchHttpClient";
|
|
40
|
+
import * as HttpServerRequest from "effect/unstable/http/HttpServerRequest";
|
|
41
|
+
import * as HttpServerResponse from "effect/unstable/http/HttpServerResponse";
|
|
42
|
+
import { BranchMissing, MergeConflict, NoMergeBase, NothingToMerge, ObjectNotFound, PullExists, PullNotFound, PullStateConflict, ReadOnlyRepo, RefConflict, RefNotFound, RepoNotFound, ValidationError, WrongObjectType, } from "./Api.js";
|
|
43
|
+
import { applyDelta } from "./Protocol/Delta.js";
|
|
44
|
+
import * as PackParser from "./Protocol/PackParser.js";
|
|
45
|
+
import { bytesToHex, concatBytes, decodeOfsDeltaOffset, decodeTypeSize, encodeCommit, encodeTypeSize, hashObject, isDeltaType, isOid, makeSha1, ObjectType, objectTypeName, parseCommit, parseTag, parseTree, treeEntryKind, utf8Encode, ZERO_OID, } from "./Protocol/ObjectCodec.js";
|
|
46
|
+
import { decodePktLines, errPkt, flushPkt, pktPayloadText, pktText, readPktLineAt, } from "./Protocol/Pkt.js";
|
|
47
|
+
import { progressMessage, pumpPackBody, sidebandFrames, } from "./Protocol/Sideband.js";
|
|
48
|
+
import { StoreError, } from "./Protocol/Store.js";
|
|
49
|
+
import { applyTreeChanges, conflictingPaths, diffTrees, } from "./Protocol/TreeDiff.js";
|
|
50
|
+
import * as Zlib from "./Protocol/Zlib.js";
|
|
51
|
+
import { runImport } from "./Jobs/Import.js";
|
|
52
|
+
import { runForkJob, snapshotStream } from "./Jobs/Fork.js";
|
|
53
|
+
import { bundleCovers, runBundleJob } from "./Jobs/Bundle.js";
|
|
54
|
+
import { runCompactJob, runGeometricMergeJob, shouldCompact, } from "./Jobs/Compact.js";
|
|
55
|
+
import { headKey, incomingKey, packKeyOf, wirePackId } from "./Store/Keys.js";
|
|
56
|
+
import { encodeHeadSnapshot } from "./Store/HeadSnapshot.js";
|
|
57
|
+
import { blobRandomAccess, sliceRandomAccess } from "./Store/PackSource.js";
|
|
58
|
+
import { SPILL_PART_BYTES } from "./Store/IncomingBody.js";
|
|
59
|
+
import { BACKPRESSURE_BYTES, makeStreamingSource, RETAIN_BYTES, } from "./Store/StreamingSource.js";
|
|
60
|
+
import { Hasher, } from "./Hasher/Hasher.js";
|
|
61
|
+
import * as PartialScan from "./Protocol/PartialScan.js";
|
|
62
|
+
import { BlobStore } from "./BlobStore.js";
|
|
63
|
+
import { runPurgeJob } from "./Jobs/Purge.js";
|
|
64
|
+
import { RegistryStore, ulid } from "./RegistryObject.js";
|
|
65
|
+
import { decodeStagedBatch } from "./PushWire.js";
|
|
66
|
+
import { computeClosure } from "./Store/Closure.js";
|
|
67
|
+
import { makeObjectStore, MAX_OBJECT_SIZE, LIVE_OBJECTS, } from "./Store/ObjectStore.js";
|
|
68
|
+
import { initRepoSchema, makeSqlClient, } from "./Store/Sql.js";
|
|
69
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
70
|
+
// Constants
|
|
71
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
72
|
+
/**
|
|
73
|
+
* Pushes up to this size are ingested straight from memory; larger ones are
|
|
74
|
+
* parked in R2 and parsed from there (DESIGN.md §3.6). A **buffering
|
|
75
|
+
* threshold, not a limit** — a push larger than this is no longer rejected.
|
|
76
|
+
*
|
|
77
|
+
* The spill threshold of the streaming receive (`receiveWireBody`): bodies
|
|
78
|
+
* up to this size are buffered and parsed from memory (the fast path, at
|
|
79
|
+
* 50 MiB the bound v1 validated for a 128 MB isolate); larger bodies are
|
|
80
|
+
* never materialized — they stream into an R2 multipart upload as they
|
|
81
|
+
* arrive and are parsed back through bounded windows.
|
|
82
|
+
*
|
|
83
|
+
* Measured on the 38 MiB alchemy-repo push: ~20 s in memory, ~37 s through
|
|
84
|
+
* R2. The R2 path costs about 2x, and is unbounded — the full 67 MiB
|
|
85
|
+
* alchemy history (44k objects) pushed in 92 s.
|
|
86
|
+
*/
|
|
87
|
+
export const MAX_PACK_BYTES = 4 * 1024 * 1024;
|
|
88
|
+
// 4 MiB (was 50, then 24): with promoted wire packs (DESIGN §22.5) the
|
|
89
|
+
// spilled path is the FAST one — it never writes blob bytes to SQLite, so
|
|
90
|
+
// staging and the staged→live flip cost milliseconds instead of seconds
|
|
91
|
+
// (a 5.7 MiB in-memory push spent 6 s in finalize on production; a 40 MiB
|
|
92
|
+
// spilled one 0.7 s). Only genuinely small pushes stay in memory.
|
|
93
|
+
// 24 MiB, down from the 50 MiB v1 validated with ONE active repo: instances
|
|
94
|
+
// of this class share an isolate, so the in-memory pack, the ingest's
|
|
95
|
+
// resolved-content LRU (20 MiB) and staging batch (8 MiB) sit beside every
|
|
96
|
+
// other active repo's working set. DESIGN §22.4 records the OOM that
|
|
97
|
+
// motivated it; the R2 path costs ~2x on the bytes above the threshold.
|
|
98
|
+
/** Objects staged per SQL transaction during ingest (DESIGN.md §16.6). */
|
|
99
|
+
/** Bytes per hasher part — the spill part size, so a part is one R2 part (DESIGN §22.7). */
|
|
100
|
+
export const HASH_PART_BYTES = 4 * 1024 * 1024;
|
|
101
|
+
/** Hasher calls in flight per push (DESIGN §22.8). */
|
|
102
|
+
export const HASH_CONCURRENCY = 8;
|
|
103
|
+
// 4 MiB (was 8): the hasher chain is sequential (each part needs the
|
|
104
|
+
// previous part's boundary), so a smaller part shortens both the tail after
|
|
105
|
+
// the upload ends and the granularity at which the upload can run ahead.
|
|
106
|
+
export const STAGE_BATCH_OBJECTS = 2048;
|
|
107
|
+
// 2048 (was 256): measured on production, staging cost tracked the number
|
|
108
|
+
// of transaction COMMITs (~100 ms each), not rows — 61 commits for a
|
|
109
|
+
// 15.6k-object push. Objects average a few KiB, so 2048 stays well under
|
|
110
|
+
// STAGE_BATCH_BYTES; the byte cap still bounds memory for large objects.
|
|
111
|
+
/** Byte budget per staging batch, so a batch of large blobs stays bounded. */
|
|
112
|
+
export const STAGE_BATCH_BYTES = 8 * 1024 * 1024;
|
|
113
|
+
// The tree-diff caps (`MAX_DIFF_FILES`, `MAX_DIFF_TREE_READS`) live with
|
|
114
|
+
// the pure walk in `Protocol/TreeDiff.ts`; re-exported here alongside the other
|
|
115
|
+
// serving-plane bounds.
|
|
116
|
+
export { MAX_DIFF_FILES, MAX_DIFF_TREE_READS } from "./Protocol/TreeDiff.js";
|
|
117
|
+
/** Max commits popped by the merge-base paint walk. */
|
|
118
|
+
export const MAX_COMPARE_WALK = 10_000;
|
|
119
|
+
/** Max commits returned in a Comparison's `commits` array. */
|
|
120
|
+
export const MAX_COMPARE_COMMITS = 250;
|
|
121
|
+
/**
|
|
122
|
+
* Max commits popped by the PR live-field walk (`getPull`). Saturation
|
|
123
|
+
* makes the numeric detail fields `null` (reason `"unknown"`); merge still
|
|
124
|
+
* works because {@link MAX_PULL_MERGE_WALK} gives the merge path a deeper
|
|
125
|
+
* budget.
|
|
126
|
+
*/
|
|
127
|
+
export const MAX_PULL_WALK = 5_000;
|
|
128
|
+
/** Deeper walk budget for `mergePull` (needs only reachability + one base). */
|
|
129
|
+
export const MAX_PULL_MERGE_WALK = 50_000;
|
|
130
|
+
/** Conflicting paths reported on a `MergeConflict` (the set may be larger). */
|
|
131
|
+
export const MAX_CONFLICT_PATHS = 20;
|
|
132
|
+
/** Agent string advertised on the wire. */
|
|
133
|
+
export const GIT_AGENT = "git-service/1";
|
|
134
|
+
/** How long a push waits for ingest memory before answering 503. */
|
|
135
|
+
export const PUSH_WAIT_TIMEOUT = "30 seconds";
|
|
136
|
+
/**
|
|
137
|
+
* Memory the Repo DO lends to concurrent push ingests, in MiB — one
|
|
138
|
+
* permit per MiB (DESIGN.md §2.1).
|
|
139
|
+
*
|
|
140
|
+
* The semaphore exists for MEMORY, not correctness: a DO is
|
|
141
|
+
* single-threaded, but its input gate is only closed across *storage*
|
|
142
|
+
* awaits, and receive-pack awaits the network and blob storage — so two
|
|
143
|
+
* pushes genuinely interleave. Correctness across that interleave is
|
|
144
|
+
* already handled by data scoping (`staged_push = pushId`, and every
|
|
145
|
+
* read filtering `staged_push IS NULL`) plus a synchronous
|
|
146
|
+
* `transactionSync` finalize. What is left is that two concurrent
|
|
147
|
+
* 50 MiB buffers would exhaust the 128 MB isolate.
|
|
148
|
+
*
|
|
149
|
+
* Bounding the resource rather than the count is what lets pushes to
|
|
150
|
+
* different branches proceed together: a normal push is kilobytes and
|
|
151
|
+
* takes one permit, so it no longer queues behind a large one.
|
|
152
|
+
*/
|
|
153
|
+
export const PUSH_MEMORY_BUDGET_MB = 64;
|
|
154
|
+
let sharedPushGate;
|
|
155
|
+
/**
|
|
156
|
+
* The push-admission semaphore, ONE per isolate (DESIGN §21.2, §22.4). DO
|
|
157
|
+
* instances of a class share an isolate, so a per-instance gate would let
|
|
158
|
+
* N repos each admit a full budget's worth of concurrent pushes.
|
|
159
|
+
*/
|
|
160
|
+
export const isolatePushGate = Effect.suspend(() => sharedPushGate === undefined
|
|
161
|
+
? Semaphore.make(PUSH_MEMORY_BUDGET_MB).pipe(Effect.tap((gate) => Effect.sync(() => {
|
|
162
|
+
sharedPushGate = gate;
|
|
163
|
+
})))
|
|
164
|
+
: Effect.succeed(sharedPushGate));
|
|
165
|
+
/**
|
|
166
|
+
* Permits a push must reserve: its buffered ceiling in MiB. A body
|
|
167
|
+
* larger than {@link MAX_PACK_BYTES} spills to blob storage instead of
|
|
168
|
+
* growing in memory, so that is the cap; an absent `content-length`
|
|
169
|
+
* (chunked upload) is charged the same worst case.
|
|
170
|
+
*/
|
|
171
|
+
export const pushPermitsFor = (contentLength) => {
|
|
172
|
+
const mib = (bytes) => Math.ceil(bytes / (1024 * 1024));
|
|
173
|
+
// What a push can hold at once, in MiB — never its body. An unknown
|
|
174
|
+
// length is treated as spilled. Memory safety beats concurrency: on a
|
|
175
|
+
// 64 MiB budget that admits one large push per isolate alongside small ones.
|
|
176
|
+
// Streaming (DESIGN §22.6–7): the feeder retains RETAIN_BYTES behind the
|
|
177
|
+
// pump and buffers BACKPRESSURE_BYTES ahead of it, plus one staging batch.
|
|
178
|
+
const spilled = mib(RETAIN_BYTES + BACKPRESSURE_BYTES + STAGE_BATCH_BYTES);
|
|
179
|
+
// In memory the caches cannot outgrow what the (small) body can inflate
|
|
180
|
+
// to, so charge the body twice (compressed + inflated) plus one for the
|
|
181
|
+
// batch, rather than the caches' ceilings.
|
|
182
|
+
const permits = contentLength === undefined ||
|
|
183
|
+
!Number.isFinite(contentLength) ||
|
|
184
|
+
contentLength > MAX_PACK_BYTES
|
|
185
|
+
? spilled
|
|
186
|
+
: mib(Math.max(contentLength, 0)) * 2 + 1;
|
|
187
|
+
return Math.max(1, Math.min(PUSH_MEMORY_BUDGET_MB, permits));
|
|
188
|
+
};
|
|
189
|
+
/** How long crashed push staging survives before the GC alarm reaps it. */
|
|
190
|
+
export const STAGING_TTL_MS = 24 * 60 * 60 * 1000;
|
|
191
|
+
/** The realm sent on wire 401s. */
|
|
192
|
+
export const WWW_AUTHENTICATE = 'Basic realm="git-service"';
|
|
193
|
+
/**
|
|
194
|
+
* Worker↔DO headers for the clone-bundle splice (DESIGN.md §11): the DO
|
|
195
|
+
* answers an eligible clone with these *instead of* the pack, and the
|
|
196
|
+
* Worker streams the named R2 object to the client. Only
|
|
197
|
+
* {@link BUNDLE_HASH_HEADER} is kept on the client-visible response, as
|
|
198
|
+
* observable proof the fast path served the clone.
|
|
199
|
+
*/
|
|
200
|
+
export const BUNDLE_KEY_HEADER = "x-git-bundle-key";
|
|
201
|
+
export const BUNDLE_HASH_HEADER = "x-git-bundle";
|
|
202
|
+
export const BUNDLE_COUNT_HEADER = "x-git-bundle-count";
|
|
203
|
+
export const BUNDLE_SIDEBAND_HEADER = "x-git-bundle-sideband";
|
|
204
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
205
|
+
// Errors
|
|
206
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
207
|
+
/**
|
|
208
|
+
* A push pack failed to ingest (malformed, oversize, checksum mismatch,
|
|
209
|
+
* missing thin base, delta error). Reported in-band as `unpack <reason>` +
|
|
210
|
+
* per-ref `ng` — never as an HTTP error.
|
|
211
|
+
*/
|
|
212
|
+
export class PackIngestError extends Schema.TaggedError()("PackIngestError", { reason: Schema.String }) {
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* A syntactically valid request that the v0 grammar does not allow
|
|
216
|
+
* (missing wants, malformed command lines, unsupported deepen flavors).
|
|
217
|
+
* Answered with an `ERR` pkt.
|
|
218
|
+
*/
|
|
219
|
+
export class WireProtocolError extends Schema.TaggedError()("WireProtocolError", { reason: Schema.String }) {
|
|
220
|
+
}
|
|
221
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
222
|
+
// Protocol choreography — pure helpers (exported for tests / future split)
|
|
223
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
224
|
+
/** Upload-pack capability list (DESIGN.md §4). */
|
|
225
|
+
export const uploadCapabilities = (defaultBranch) => `multi_ack_detailed no-done side-band-64k shallow ofs-delta agent=${GIT_AGENT} symref=HEAD:refs/heads/${defaultBranch} object-format=sha1`;
|
|
226
|
+
/** Receive-pack capability list (DESIGN.md §4). */
|
|
227
|
+
export const receiveCapabilities = () => `report-status report-status-v2 delete-refs side-band-64k atomic ofs-delta object-format=sha1 agent=${GIT_AGENT}`;
|
|
228
|
+
/**
|
|
229
|
+
* Builds the v0 `info/refs` advertisement (with `# service=` prelude):
|
|
230
|
+
* HEAD first with the capability line, refs sorted, annotated tags peeled
|
|
231
|
+
* (`^{}` lines), zero-id `capabilities^{}` on an empty repo.
|
|
232
|
+
*/
|
|
233
|
+
export const buildAdvertisement = (options) => {
|
|
234
|
+
const caps = options.service === "git-upload-pack"
|
|
235
|
+
? uploadCapabilities(options.defaultBranch)
|
|
236
|
+
: receiveCapabilities();
|
|
237
|
+
const parts = [
|
|
238
|
+
pktText(`# service=${options.service}`),
|
|
239
|
+
flushPkt,
|
|
240
|
+
];
|
|
241
|
+
const lines = [];
|
|
242
|
+
const headRef = options.refs.find((ref) => ref.name === `refs/heads/${options.defaultBranch}`);
|
|
243
|
+
if (options.service === "git-upload-pack" && headRef !== undefined) {
|
|
244
|
+
lines.push(`${headRef.oid} HEAD`);
|
|
245
|
+
}
|
|
246
|
+
for (const ref of options.refs) {
|
|
247
|
+
lines.push(`${ref.oid} ${ref.name}`);
|
|
248
|
+
if (ref.peeled !== undefined) {
|
|
249
|
+
lines.push(`${ref.peeled} ${ref.name}^{}`);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
if (lines.length === 0) {
|
|
253
|
+
parts.push(pktText(`${ZERO_OID} capabilities^{}\0${caps}`));
|
|
254
|
+
}
|
|
255
|
+
else {
|
|
256
|
+
lines.forEach((line, index) => {
|
|
257
|
+
parts.push(index === 0 ? pktText(`${line}\0${caps}`) : pktText(line));
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
parts.push(flushPkt);
|
|
261
|
+
return concatBytes(parts);
|
|
262
|
+
};
|
|
263
|
+
/**
|
|
264
|
+
* Parses a v0 upload-pack POST body (already gunzipped) into wants /
|
|
265
|
+
* shallow / deepen / haves / done. Rejects `deepen-since` / `deepen-not` /
|
|
266
|
+
* `filter` (not advertised) with {@link WireProtocolError}.
|
|
267
|
+
*/
|
|
268
|
+
export const parseUploadPackRequest = (pkts) => Effect.suspend(() => {
|
|
269
|
+
const wants = [];
|
|
270
|
+
const haves = [];
|
|
271
|
+
const clientShallow = [];
|
|
272
|
+
let done = false;
|
|
273
|
+
let depth;
|
|
274
|
+
let capabilities = new Set();
|
|
275
|
+
for (const pkt of pkts) {
|
|
276
|
+
if (pkt._tag !== "data")
|
|
277
|
+
continue;
|
|
278
|
+
const text = pktPayloadText(pkt.payload);
|
|
279
|
+
if (text === "done") {
|
|
280
|
+
done = true;
|
|
281
|
+
continue;
|
|
282
|
+
}
|
|
283
|
+
if (text.startsWith("want ")) {
|
|
284
|
+
let rest = text.slice(5);
|
|
285
|
+
if (wants.length === 0) {
|
|
286
|
+
const space = rest.indexOf(" ");
|
|
287
|
+
if (space !== -1) {
|
|
288
|
+
capabilities = new Set(rest
|
|
289
|
+
.slice(space + 1)
|
|
290
|
+
.split(" ")
|
|
291
|
+
.filter(Boolean));
|
|
292
|
+
rest = rest.slice(0, space);
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
if (!isOid(rest)) {
|
|
296
|
+
return Effect.fail(new WireProtocolError({ reason: `malformed want line: ${text}` }));
|
|
297
|
+
}
|
|
298
|
+
wants.push(rest);
|
|
299
|
+
continue;
|
|
300
|
+
}
|
|
301
|
+
if (text.startsWith("have ")) {
|
|
302
|
+
const oid = text.slice(5, 45);
|
|
303
|
+
if (isOid(oid))
|
|
304
|
+
haves.push(oid);
|
|
305
|
+
continue;
|
|
306
|
+
}
|
|
307
|
+
if (text.startsWith("shallow ")) {
|
|
308
|
+
const oid = text.slice(8);
|
|
309
|
+
if (!isOid(oid)) {
|
|
310
|
+
return Effect.fail(new WireProtocolError({
|
|
311
|
+
reason: `malformed shallow line: ${text}`,
|
|
312
|
+
}));
|
|
313
|
+
}
|
|
314
|
+
clientShallow.push(oid);
|
|
315
|
+
continue;
|
|
316
|
+
}
|
|
317
|
+
if (text.startsWith("deepen ")) {
|
|
318
|
+
const n = Number.parseInt(text.slice(7), 10);
|
|
319
|
+
if (!Number.isInteger(n) || n <= 0) {
|
|
320
|
+
return Effect.fail(new WireProtocolError({ reason: `malformed deepen line: ${text}` }));
|
|
321
|
+
}
|
|
322
|
+
depth = n;
|
|
323
|
+
continue;
|
|
324
|
+
}
|
|
325
|
+
if (text.startsWith("deepen-since ") || text.startsWith("deepen-not ")) {
|
|
326
|
+
return Effect.fail(new WireProtocolError({
|
|
327
|
+
reason: `${text.split(" ")[0]} is not supported`,
|
|
328
|
+
}));
|
|
329
|
+
}
|
|
330
|
+
if (text.startsWith("filter ")) {
|
|
331
|
+
return Effect.fail(new WireProtocolError({ reason: "filter is not supported" }));
|
|
332
|
+
}
|
|
333
|
+
// ignore unknown lines defensively
|
|
334
|
+
}
|
|
335
|
+
if (wants.length === 0) {
|
|
336
|
+
return Effect.fail(new WireProtocolError({ reason: "upload-pack request has no wants" }));
|
|
337
|
+
}
|
|
338
|
+
return Effect.succeed({
|
|
339
|
+
wants,
|
|
340
|
+
haves,
|
|
341
|
+
done,
|
|
342
|
+
depth,
|
|
343
|
+
clientShallow,
|
|
344
|
+
capabilities,
|
|
345
|
+
});
|
|
346
|
+
});
|
|
347
|
+
const REF_NAME_REGEX = /^refs\/[^\s~^:?*\[\\]+$/;
|
|
348
|
+
/**
|
|
349
|
+
* Parses a v0 receive-pack POST body (already gunzipped): command
|
|
350
|
+
* pkt-lines (first carries `\0caps`) up to the flush, leaving the raw pack
|
|
351
|
+
* bytes at `packStart`. Detects the empty-flush probe (DESIGN.md §2.3
|
|
352
|
+
* Push step 2).
|
|
353
|
+
*/
|
|
354
|
+
export const parseReceivePackRequest = (body) => Effect.suspend(() => {
|
|
355
|
+
const commands = [];
|
|
356
|
+
let capabilities = new Set();
|
|
357
|
+
let pos = 0;
|
|
358
|
+
let first = true;
|
|
359
|
+
for (;;) {
|
|
360
|
+
if (pos >= body.length) {
|
|
361
|
+
// Body ended without a flush: only legal as the bare probe of an
|
|
362
|
+
// entirely empty body.
|
|
363
|
+
if (commands.length === 0 && pos === 0) {
|
|
364
|
+
return Effect.succeed({
|
|
365
|
+
commands: [],
|
|
366
|
+
capabilities,
|
|
367
|
+
packStart: body.length,
|
|
368
|
+
probe: true,
|
|
369
|
+
});
|
|
370
|
+
}
|
|
371
|
+
return Effect.fail(new WireProtocolError({
|
|
372
|
+
reason: "receive-pack request ended before flush",
|
|
373
|
+
}));
|
|
374
|
+
}
|
|
375
|
+
const r = readPktLineAt(body, pos);
|
|
376
|
+
if (r._tag === "incomplete" || r._tag === "invalid") {
|
|
377
|
+
return Effect.fail(new WireProtocolError({
|
|
378
|
+
reason: r._tag === "invalid"
|
|
379
|
+
? r.reason
|
|
380
|
+
: "truncated receive-pack request",
|
|
381
|
+
}));
|
|
382
|
+
}
|
|
383
|
+
pos = r.next;
|
|
384
|
+
if (r.pkt._tag === "flush") {
|
|
385
|
+
return Effect.succeed({
|
|
386
|
+
commands,
|
|
387
|
+
capabilities,
|
|
388
|
+
packStart: pos,
|
|
389
|
+
probe: commands.length === 0 && pos >= body.length,
|
|
390
|
+
});
|
|
391
|
+
}
|
|
392
|
+
if (r.pkt._tag !== "data")
|
|
393
|
+
continue;
|
|
394
|
+
let text = pktPayloadText(r.pkt.payload);
|
|
395
|
+
if (first) {
|
|
396
|
+
const nul = text.indexOf("\0");
|
|
397
|
+
if (nul !== -1) {
|
|
398
|
+
capabilities = new Set(text
|
|
399
|
+
.slice(nul + 1)
|
|
400
|
+
.split(" ")
|
|
401
|
+
.filter(Boolean));
|
|
402
|
+
text = text.slice(0, nul);
|
|
403
|
+
}
|
|
404
|
+
first = false;
|
|
405
|
+
}
|
|
406
|
+
const oldOid = text.slice(0, 40);
|
|
407
|
+
const newOid = text.slice(41, 81);
|
|
408
|
+
const ref = text.slice(82);
|
|
409
|
+
if (!isOid(oldOid) ||
|
|
410
|
+
!isOid(newOid) ||
|
|
411
|
+
text[40] !== " " ||
|
|
412
|
+
text[81] !== " " ||
|
|
413
|
+
!REF_NAME_REGEX.test(ref)) {
|
|
414
|
+
return Effect.fail(new WireProtocolError({ reason: `malformed command line: ${text}` }));
|
|
415
|
+
}
|
|
416
|
+
commands.push({ oldOid, newOid, ref });
|
|
417
|
+
}
|
|
418
|
+
});
|
|
419
|
+
/** The 12-byte pack header: `PACK`, version 2, entry count. */
|
|
420
|
+
export const packHeader = (count) => {
|
|
421
|
+
const out = new Uint8Array(12);
|
|
422
|
+
out.set(utf8Encode("PACK"), 0);
|
|
423
|
+
const view = new DataView(out.buffer);
|
|
424
|
+
view.setUint32(4, 2);
|
|
425
|
+
view.setUint32(8, count);
|
|
426
|
+
return out;
|
|
427
|
+
};
|
|
428
|
+
/**
|
|
429
|
+
* The §3.5 no-delta pack emitter: header + per-entry
|
|
430
|
+
* `varint(type,size) + stored zdata` (verbatim — zero compression CPU) +
|
|
431
|
+
* incremental SHA-1 trailer. Constant memory; the manifest is already
|
|
432
|
+
* materialized so the count is known upfront.
|
|
433
|
+
*/
|
|
434
|
+
export const packStream = (entries, objects) => Stream.suspend(() => {
|
|
435
|
+
const sha = makeSha1();
|
|
436
|
+
const tap = (bytes) => {
|
|
437
|
+
sha.update(bytes);
|
|
438
|
+
return bytes;
|
|
439
|
+
};
|
|
440
|
+
const header = Stream.sync(() => tap(packHeader(entries.length)));
|
|
441
|
+
const body = packEntryStream(entries, objects).pipe(Stream.map(tap));
|
|
442
|
+
const trailer = Stream.sync(() => sha.digest());
|
|
443
|
+
return header.pipe(Stream.concat(body), Stream.concat(trailer));
|
|
444
|
+
});
|
|
445
|
+
/**
|
|
446
|
+
* The entry stream alone — no header, no trailer. Because entries are
|
|
447
|
+
* stored non-delta (`varint(type,size) + zdata`), entry streams from
|
|
448
|
+
* different sources concatenate into one valid pack under a rewritten
|
|
449
|
+
* header and a fresh trailer. That is what lets a clone be served as
|
|
450
|
+
* "bundle bytes + a small delta" (DESIGN.md §21.2), and it is the same
|
|
451
|
+
* property geometric pack merging relies on.
|
|
452
|
+
*/
|
|
453
|
+
export const packEntryStream = (entries, objects) => objects.packEntries !== undefined
|
|
454
|
+
? objects.packEntries(entries)
|
|
455
|
+
: Stream.fromIterable(entries).pipe(Stream.flatMap((entry) => Stream.sync(() => encodeTypeSize(entry.type, entry.size)).pipe(Stream.concat(objects.readZData(entry.oid)))));
|
|
456
|
+
/** Bounded LRU of inflated contents shared across delta resolution. */
|
|
457
|
+
const makeContentCache = (budget) => {
|
|
458
|
+
const map = new Map();
|
|
459
|
+
let total = 0;
|
|
460
|
+
return {
|
|
461
|
+
get: (key) => {
|
|
462
|
+
const value = map.get(key);
|
|
463
|
+
if (value !== undefined) {
|
|
464
|
+
map.delete(key);
|
|
465
|
+
map.set(key, value);
|
|
466
|
+
}
|
|
467
|
+
return value;
|
|
468
|
+
},
|
|
469
|
+
set: (key, value) => {
|
|
470
|
+
if (value.byteLength > budget || map.has(key))
|
|
471
|
+
return;
|
|
472
|
+
map.set(key, value);
|
|
473
|
+
total += value.byteLength;
|
|
474
|
+
for (const [k, v] of map) {
|
|
475
|
+
if (total <= budget)
|
|
476
|
+
break;
|
|
477
|
+
map.delete(k);
|
|
478
|
+
total -= v.byteLength;
|
|
479
|
+
}
|
|
480
|
+
},
|
|
481
|
+
};
|
|
482
|
+
};
|
|
483
|
+
/** Delta-resolution content cache budget (DESIGN.md §3.6): 20 MiB. */
|
|
484
|
+
const CACHE_BUDGET = 20 * 1024 * 1024;
|
|
485
|
+
/** Maximum delta-chain depth tolerated (git's own default is 50). */
|
|
486
|
+
const MAX_DELTA_DEPTH = 64;
|
|
487
|
+
/** An {@link IngestStore} over a full {@link ObjectStore}. */
|
|
488
|
+
export const ingestStoreOf = (store) => ({
|
|
489
|
+
insertStagedBatch: store.insertStagedBatch,
|
|
490
|
+
readBase: (oid) => store
|
|
491
|
+
.getMeta(oid)
|
|
492
|
+
.pipe(Effect.flatMap((meta) => meta === undefined
|
|
493
|
+
? Effect.succeed(undefined)
|
|
494
|
+
: store
|
|
495
|
+
.readContent(oid)
|
|
496
|
+
.pipe(Effect.map((content) => ({ type: meta.type, content }))))),
|
|
497
|
+
});
|
|
498
|
+
/**
|
|
499
|
+
* Single-pass buffered pack ingest (DESIGN.md §3.6): parse entries,
|
|
500
|
+
* store non-delta compressed spans **verbatim**, resolve ofs/ref deltas
|
|
501
|
+
* (thin bases from the live store), enforce the 64 MiB object cap, verify
|
|
502
|
+
* the trailer SHA-1, and stage everything under `pushId`.
|
|
503
|
+
*
|
|
504
|
+
* The v1.x streaming upgrade seam: this function's only view of the pack
|
|
505
|
+
* is `pack: Uint8Array` random access — swapping in an R2-backed
|
|
506
|
+
* `RandomAccess` touches this implementation, not the protocol drivers.
|
|
507
|
+
*/
|
|
508
|
+
/**
|
|
509
|
+
* Ingests a pack from a {@link RandomAccess} source — the path that has **no
|
|
510
|
+
* size cap** (DESIGN.md §3.6). Memory is bounded by the source's read
|
|
511
|
+
* window and the delta LRU rather than by the pack, so the source can be an
|
|
512
|
+
* R2 object of any size (see `Store/PackSource.ts`).
|
|
513
|
+
*
|
|
514
|
+
* Delegates the wire-format work to the pure `PackParser` (which the pack
|
|
515
|
+
* fixtures in `test/pack.test.ts` cover directly) and does the repo-side
|
|
516
|
+
* work in its sink: stage the object, and record commit-graph edges.
|
|
517
|
+
* Blobs are staged without inflating — only commits, trees and tags need
|
|
518
|
+
* their content parsed, and those are small.
|
|
519
|
+
*/
|
|
520
|
+
export const ingestPackFrom = (source, options) => Effect.gen(function* () {
|
|
521
|
+
const { store, pushId } = options;
|
|
522
|
+
const commits = [];
|
|
523
|
+
const referenced = new Set();
|
|
524
|
+
const referencedParents = new Set();
|
|
525
|
+
const record = Effect.fn(function* (oid, type, content) {
|
|
526
|
+
switch (type) {
|
|
527
|
+
case ObjectType.commit: {
|
|
528
|
+
const parsed = yield* parseCommit(content).pipe(Effect.mapError((error) => new PackIngestError({
|
|
529
|
+
reason: `bad commit ${oid}: ${error.reason}`,
|
|
530
|
+
})));
|
|
531
|
+
commits.push({
|
|
532
|
+
oid,
|
|
533
|
+
tree: parsed.tree,
|
|
534
|
+
parents: parsed.parents,
|
|
535
|
+
commitTime: parsed.committer.when,
|
|
536
|
+
});
|
|
537
|
+
referenced.add(parsed.tree);
|
|
538
|
+
for (const parent of parsed.parents)
|
|
539
|
+
referencedParents.add(parent);
|
|
540
|
+
return;
|
|
541
|
+
}
|
|
542
|
+
case ObjectType.tree: {
|
|
543
|
+
const parsed = yield* parseTree(content).pipe(Effect.mapError((error) => new PackIngestError({
|
|
544
|
+
reason: `bad tree ${oid}: ${error.reason}`,
|
|
545
|
+
})));
|
|
546
|
+
for (const entry of parsed) {
|
|
547
|
+
if (treeEntryKind(entry.mode) !== "commit") {
|
|
548
|
+
referenced.add(entry.oid);
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
return;
|
|
552
|
+
}
|
|
553
|
+
case ObjectType.tag: {
|
|
554
|
+
const parsed = yield* parseTag(content).pipe(Effect.mapError((error) => new PackIngestError({
|
|
555
|
+
reason: `bad tag ${oid}: ${error.reason}`,
|
|
556
|
+
})));
|
|
557
|
+
referenced.add(parsed.object);
|
|
558
|
+
return;
|
|
559
|
+
}
|
|
560
|
+
case ObjectType.blob:
|
|
561
|
+
return;
|
|
562
|
+
}
|
|
563
|
+
});
|
|
564
|
+
let batch = [];
|
|
565
|
+
let batchBytes = 0;
|
|
566
|
+
let promoted = 0;
|
|
567
|
+
/** Time spent in SQL staging; the rest of ingest is CPU. */
|
|
568
|
+
let stageMs = 0;
|
|
569
|
+
const flush = Effect.fn(function* () {
|
|
570
|
+
if (batch.length === 0)
|
|
571
|
+
return;
|
|
572
|
+
const pending = batch;
|
|
573
|
+
batch = [];
|
|
574
|
+
batchBytes = 0;
|
|
575
|
+
const target = options.promote?.() ??
|
|
576
|
+
(spilling && options.spill !== undefined
|
|
577
|
+
? { packId: options.spill.packId, base: options.spill.packStart }
|
|
578
|
+
: undefined);
|
|
579
|
+
const staged = [];
|
|
580
|
+
for (const entry of pending) {
|
|
581
|
+
const pack = entry.pack ??
|
|
582
|
+
(target !== undefined &&
|
|
583
|
+
!entry.fromDelta &&
|
|
584
|
+
entry.type === ObjectType.blob &&
|
|
585
|
+
entry.dataOffset >= 0
|
|
586
|
+
? { packId: target.packId, offset: target.base + entry.dataOffset }
|
|
587
|
+
: undefined);
|
|
588
|
+
if (pack !== undefined)
|
|
589
|
+
promoted += 1;
|
|
590
|
+
// A promoted row needs no bytes; an inline row needs its zdata —
|
|
591
|
+
// the hasher path did not ship it, so read the span back.
|
|
592
|
+
const zdata = entry.zdata ??
|
|
593
|
+
(pack === undefined
|
|
594
|
+
? Uint8Array.from(readSpan?.(entry.dataOffset, entry.span ?? 0) ??
|
|
595
|
+
(yield* source.read(entry.dataOffset, entry.span ?? 0)))
|
|
596
|
+
: new Uint8Array(0));
|
|
597
|
+
staged.push({
|
|
598
|
+
oid: entry.oid,
|
|
599
|
+
type: entry.type,
|
|
600
|
+
size: entry.size,
|
|
601
|
+
zdata,
|
|
602
|
+
zsize: entry.zdata?.byteLength ?? entry.span,
|
|
603
|
+
pack,
|
|
604
|
+
});
|
|
605
|
+
}
|
|
606
|
+
const at = yield* Effect.sync(() => performance.now());
|
|
607
|
+
yield* store.insertStagedBatch(pushId, staged);
|
|
608
|
+
stageMs += yield* Effect.sync(() => performance.now() - at);
|
|
609
|
+
});
|
|
610
|
+
const phases = {};
|
|
611
|
+
/** The spill's multipart upload, once the pump decided to spill. */
|
|
612
|
+
let upload;
|
|
613
|
+
let spilling = false;
|
|
614
|
+
/** Set once the spilled object is complete: it is the wire pack. */
|
|
615
|
+
let parkedKey;
|
|
616
|
+
/** Set once the resolved pack(s) are written (DESIGN §22.13). */
|
|
617
|
+
let resolvedKey;
|
|
618
|
+
const resolvedKeys = [];
|
|
619
|
+
/**
|
|
620
|
+
* Delta-resolved blobs held back from staging while the body spills:
|
|
621
|
+
* their fresh zlib goes into one resolved pack in blob storage and the
|
|
622
|
+
* rows become coordinates, so the DO never writes those bytes.
|
|
623
|
+
*/
|
|
624
|
+
const resolvedBlobs = [];
|
|
625
|
+
/** In-memory span reads over the retained parts (set by the pump). */
|
|
626
|
+
let readSpan;
|
|
627
|
+
/**
|
|
628
|
+
* Stages a run of resolved entries (DESIGN §22.5): the parser's
|
|
629
|
+
* synchronous fast path hands over up to SINK_BATCH non-delta entries
|
|
630
|
+
* per fiber hop; delta-resolved entries arrive one at a time.
|
|
631
|
+
*/
|
|
632
|
+
/** Every oid this push stages: connectivity only asks the store about the rest. */
|
|
633
|
+
const stagedOids = new Set();
|
|
634
|
+
const stage = (entries) => Effect.gen(function* () {
|
|
635
|
+
for (const entry of entries) {
|
|
636
|
+
stagedOids.add(entry.oid);
|
|
637
|
+
if (spilling &&
|
|
638
|
+
entry.fromDelta &&
|
|
639
|
+
entry.type === ObjectType.blob &&
|
|
640
|
+
entry.pack === undefined &&
|
|
641
|
+
entry.zdata !== undefined) {
|
|
642
|
+
resolvedBlobs.push(entry);
|
|
643
|
+
continue;
|
|
644
|
+
}
|
|
645
|
+
batch.push(entry);
|
|
646
|
+
// Counted as inline until the flush decides; promoted rows carry
|
|
647
|
+
// no BLOB, so this over-counts — safe for a memory cap.
|
|
648
|
+
batchBytes += entry.zdata?.byteLength ?? entry.span ?? 0;
|
|
649
|
+
if (batch.length >= STAGE_BATCH_OBJECTS ||
|
|
650
|
+
batchBytes >= STAGE_BATCH_BYTES) {
|
|
651
|
+
yield* flush();
|
|
652
|
+
}
|
|
653
|
+
if (entry.type !== ObjectType.blob) {
|
|
654
|
+
if (entry.content === undefined) {
|
|
655
|
+
return yield* new PackIngestError({
|
|
656
|
+
reason: `no content for ${entry.oid} (type ${entry.type})`,
|
|
657
|
+
});
|
|
658
|
+
}
|
|
659
|
+
yield* record(entry.oid, entry.type, entry.content);
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
});
|
|
663
|
+
/**
|
|
664
|
+
* The hasher pipeline (DESIGN §22.7): pump the pack in parts through
|
|
665
|
+
* the hasher; every part carries the previous part's incomplete tail.
|
|
666
|
+
* The DO's own CPU here is a memcpy, the trailer SHA-1 and staging.
|
|
667
|
+
*/
|
|
668
|
+
const pumpThroughHasher = (hasher) => Effect.gen(function* () {
|
|
669
|
+
const spill = options.spill;
|
|
670
|
+
// Spill parts (uniform, ≥ 5 MiB for R2) and hash chunks: a hasher
|
|
671
|
+
// may want smaller chunks than a part (a Lambda's 6 MB payload);
|
|
672
|
+
// chunks then divide parts and the pump uploads the parts itself.
|
|
673
|
+
const partBytes = options.partBytes ??
|
|
674
|
+
(spill === undefined ? HASH_PART_BYTES : SPILL_PART_BYTES);
|
|
675
|
+
const wanted = hasher.chunkBytes ?? partBytes;
|
|
676
|
+
const hashBytes = wanted < partBytes && partBytes % wanted === 0 ? wanted : partBytes;
|
|
677
|
+
const asIngest = (error) => new PackIngestError({
|
|
678
|
+
reason: `${error._tag}${error.reason === undefined ? "" : `: ${error.reason}`}`,
|
|
679
|
+
});
|
|
680
|
+
const header = yield* source.read(0, 12);
|
|
681
|
+
if (header.length < 12 ||
|
|
682
|
+
header[0] !== 0x50 ||
|
|
683
|
+
header[1] !== 0x41 ||
|
|
684
|
+
header[2] !== 0x43 ||
|
|
685
|
+
header[3] !== 0x4b) {
|
|
686
|
+
return yield* new PackIngestError({ reason: "bad pack magic" });
|
|
687
|
+
}
|
|
688
|
+
const count = new DataView(header.buffer, header.byteOffset).getUint32(8);
|
|
689
|
+
// Trailer SHA-1 over [0, total − 20): hash with a 20-byte lag, so
|
|
690
|
+
// the last 20 bytes seen are the trailer itself.
|
|
691
|
+
const trailerSha = makeSha1();
|
|
692
|
+
let lag = new Uint8Array(0);
|
|
693
|
+
const feed = (bytes) => {
|
|
694
|
+
const joined = lag.length === 0 ? bytes : concatBytes([lag, bytes]);
|
|
695
|
+
if (joined.length > 20) {
|
|
696
|
+
trailerSha.update(joined.subarray(0, joined.length - 20));
|
|
697
|
+
lag = Uint8Array.from(joined.subarray(joined.length - 20));
|
|
698
|
+
}
|
|
699
|
+
else {
|
|
700
|
+
lag = Uint8Array.from(joined);
|
|
701
|
+
}
|
|
702
|
+
};
|
|
703
|
+
const known = new Map(); // by header offset
|
|
704
|
+
const knownByOid = new Map();
|
|
705
|
+
const unresolved = [];
|
|
706
|
+
// Raw-chunk dispatch (DESIGN §22.9–10): NO scanning here. Every
|
|
707
|
+
// chunk goes to a hasher as it arrives (bounded concurrency), which
|
|
708
|
+
// resyncs to the first entry boundary inside the chunk and scans and
|
|
709
|
+
// hashes from there — and, when the body spills, writes the chunk
|
|
710
|
+
// as its part of the multipart upload. Results are consumed in
|
|
711
|
+
// chunk order, concurrently with the receive; the one entry
|
|
712
|
+
// straddling each chunk edge is stitched from the neighbouring
|
|
713
|
+
// payloads and hashed by a small extra call. A boundary that does
|
|
714
|
+
// not line up (a resync false positive) falls back to a sequential
|
|
715
|
+
// rescan of that chunk from the known boundary.
|
|
716
|
+
const gate = yield* Semaphore.make(hasher.concurrency ?? HASH_CONCURRENCY);
|
|
717
|
+
const chunks = [];
|
|
718
|
+
const bytesFrom = (from, to) => {
|
|
719
|
+
const pieces = [];
|
|
720
|
+
for (const c of chunks) {
|
|
721
|
+
const start = Math.max(from, c.base);
|
|
722
|
+
const end = Math.min(to, c.base + c.payload.length);
|
|
723
|
+
if (end > start)
|
|
724
|
+
pieces.push(c.payload.subarray(start - c.base, end - c.base));
|
|
725
|
+
}
|
|
726
|
+
if (pieces.length === 1)
|
|
727
|
+
return pieces[0];
|
|
728
|
+
// Neighbouring chunks are views of one slab: hand out one view.
|
|
729
|
+
const first = pieces[0];
|
|
730
|
+
let contiguous = true;
|
|
731
|
+
let end = first.byteOffset + first.byteLength;
|
|
732
|
+
for (let i = 1; i < pieces.length; i++) {
|
|
733
|
+
const piece = pieces[i];
|
|
734
|
+
if (piece.buffer !== first.buffer || piece.byteOffset !== end) {
|
|
735
|
+
contiguous = false;
|
|
736
|
+
break;
|
|
737
|
+
}
|
|
738
|
+
end += piece.byteLength;
|
|
739
|
+
}
|
|
740
|
+
return contiguous
|
|
741
|
+
? new Uint8Array(first.buffer, first.byteOffset, end - first.byteOffset)
|
|
742
|
+
: concatBytes(pieces);
|
|
743
|
+
};
|
|
744
|
+
// Retained payloads serve every span read (inline rows, delta
|
|
745
|
+
// bases and deltas) so nothing goes back to the source or the
|
|
746
|
+
// spilled object during ingest.
|
|
747
|
+
readSpan = (at, length) => {
|
|
748
|
+
const bytes = bytesFrom(at, at + length);
|
|
749
|
+
return bytes.length === length ? bytes : undefined;
|
|
750
|
+
};
|
|
751
|
+
const stageResult = (payload, base, result) => Effect.gen(function* () {
|
|
752
|
+
const incoming = [];
|
|
753
|
+
for (const e of result.entries) {
|
|
754
|
+
// A hasher may omit non-blob content to bound its response
|
|
755
|
+
// (a Lambda): inflate it here from the fresh zdata or the
|
|
756
|
+
// retained span — trees, commits and tags are small.
|
|
757
|
+
const content = e.content ??
|
|
758
|
+
(e.type === ObjectType.blob
|
|
759
|
+
? undefined
|
|
760
|
+
: yield* Zlib.inflate(e.zdata ??
|
|
761
|
+
payload.subarray(e.dataOffset - base, e.dataOffset - base + e.span)).pipe(Effect.mapError(asIngest)));
|
|
762
|
+
const item = {
|
|
763
|
+
oid: e.oid,
|
|
764
|
+
type: e.type,
|
|
765
|
+
dataOffset: e.dataOffset,
|
|
766
|
+
span: e.span,
|
|
767
|
+
zdata: e.zdata,
|
|
768
|
+
content,
|
|
769
|
+
};
|
|
770
|
+
known.set(e.offset, item);
|
|
771
|
+
knownByOid.set(e.oid, item);
|
|
772
|
+
incoming.push({
|
|
773
|
+
oid: e.oid,
|
|
774
|
+
type: e.type,
|
|
775
|
+
size: e.size,
|
|
776
|
+
zdata: e.zdata ??
|
|
777
|
+
payload.subarray(e.dataOffset - base, e.dataOffset - base + e.span),
|
|
778
|
+
span: e.span,
|
|
779
|
+
dataOffset: e.dataOffset,
|
|
780
|
+
fromDelta: e.zdata !== undefined,
|
|
781
|
+
content,
|
|
782
|
+
});
|
|
783
|
+
}
|
|
784
|
+
yield* stage(incoming);
|
|
785
|
+
// Batches flush by size (STAGE_BATCH_OBJECTS / _BYTES), not per
|
|
786
|
+
// chunk: the retained parts hold every span until ingest ends.
|
|
787
|
+
for (const u of result.unresolved)
|
|
788
|
+
unresolved.push(u);
|
|
789
|
+
return result.count;
|
|
790
|
+
});
|
|
791
|
+
// ── phase 1 (producer): read parts as they arrive, dispatch each ──
|
|
792
|
+
// Wall-clock phase split (Date.now advances across awaits; the
|
|
793
|
+
// platform's cpuTime is the CPU attribution): `PushStats.phases`.
|
|
794
|
+
const pumpStarted = Date.now();
|
|
795
|
+
let regionCalls = 0;
|
|
796
|
+
// Each part's identity arrives after its upload; joined before
|
|
797
|
+
// the multipart upload is completed, never on the scan path.
|
|
798
|
+
const parts = [];
|
|
799
|
+
let producerDone = false;
|
|
800
|
+
const wakers = [];
|
|
801
|
+
const notifyConsumer = () => {
|
|
802
|
+
for (const w of wakers.splice(0))
|
|
803
|
+
w();
|
|
804
|
+
};
|
|
805
|
+
const awaitChunk = (k) => Effect.suspend(() => k < chunks.length || producerDone
|
|
806
|
+
? Effect.void
|
|
807
|
+
: Effect.callback((resume) => {
|
|
808
|
+
wakers.push(() => resume(Effect.void));
|
|
809
|
+
}));
|
|
810
|
+
const availableEnd = () => {
|
|
811
|
+
const last = chunks[chunks.length - 1];
|
|
812
|
+
return last === undefined ? 12 : last.base + last.payload.length;
|
|
813
|
+
};
|
|
814
|
+
const dispatch = (payload, opts) => Effect.forkChild(Semaphore.withPermits(gate, 1)(hasher
|
|
815
|
+
.hashPart(payload, {
|
|
816
|
+
base: opts.base,
|
|
817
|
+
skip: opts.skip,
|
|
818
|
+
remaining: count,
|
|
819
|
+
maxObjectSize: MAX_OBJECT_SIZE,
|
|
820
|
+
resync: opts.resync,
|
|
821
|
+
spill: upload === undefined ||
|
|
822
|
+
spill === undefined ||
|
|
823
|
+
!hasher.writesSpill
|
|
824
|
+
? undefined
|
|
825
|
+
: {
|
|
826
|
+
key: spill.key,
|
|
827
|
+
uploadId: upload.uploadId,
|
|
828
|
+
partNumber: opts.partNumber,
|
|
829
|
+
},
|
|
830
|
+
})
|
|
831
|
+
.pipe(Effect.mapError(asIngest))));
|
|
832
|
+
const produce = Effect.gen(function* () {
|
|
833
|
+
if (spill === undefined) {
|
|
834
|
+
// Pack-relative parts from the (in-memory or spilled) source.
|
|
835
|
+
feed(header);
|
|
836
|
+
let offset = 12;
|
|
837
|
+
let index = 0;
|
|
838
|
+
while (true) {
|
|
839
|
+
const chunk = yield* source.read(offset, partBytes);
|
|
840
|
+
if (chunk.length === 0)
|
|
841
|
+
break;
|
|
842
|
+
feed(chunk);
|
|
843
|
+
const fiber = yield* dispatch(chunk, {
|
|
844
|
+
base: offset,
|
|
845
|
+
skip: 0,
|
|
846
|
+
resync: index > 0,
|
|
847
|
+
partNumber: index + 1,
|
|
848
|
+
});
|
|
849
|
+
chunks.push({ index, base: offset, payload: chunk, fiber });
|
|
850
|
+
offset += chunk.length;
|
|
851
|
+
index += 1;
|
|
852
|
+
notifyConsumer();
|
|
853
|
+
source.release?.(offset);
|
|
854
|
+
if (chunk.length < partBytes)
|
|
855
|
+
break;
|
|
856
|
+
}
|
|
857
|
+
return;
|
|
858
|
+
}
|
|
859
|
+
// Body-aligned parts (DESIGN §22.10): part k is body
|
|
860
|
+
// [k·P, (k+1)·P); the first carries the command section and
|
|
861
|
+
// the pack header before its first entry (`skip`). Chunks of
|
|
862
|
+
// `hashBytes` divide the parts.
|
|
863
|
+
const { body, packStart } = spill;
|
|
864
|
+
const uploadGate = yield* Semaphore.make(3);
|
|
865
|
+
let partStart = 0;
|
|
866
|
+
/** Upload body [partStart, end) as the next part (pump-owned spill). */
|
|
867
|
+
const uploadPart = (end) => Effect.gen(function* () {
|
|
868
|
+
if (upload === undefined || end <= partStart)
|
|
869
|
+
return;
|
|
870
|
+
const settled = upload;
|
|
871
|
+
const partNumber = Math.floor(partStart / partBytes) + 1;
|
|
872
|
+
const bytes = bytesFrom(partStart - packStart, end - packStart);
|
|
873
|
+
partStart = end;
|
|
874
|
+
const fiber = yield* Effect.forkDetach(Semaphore.withPermits(uploadGate, 1)(spill.blobs
|
|
875
|
+
.uploadPart(spill.key, settled.uploadId, partNumber, bytes)
|
|
876
|
+
.pipe(Effect.mapError((error) => new PackIngestError({
|
|
877
|
+
reason: `spill part ${partNumber}: ${error.reason}`,
|
|
878
|
+
})), Effect.provide(RuntimeContext.phantom))));
|
|
879
|
+
parts.push(Fiber.join(fiber));
|
|
880
|
+
});
|
|
881
|
+
let index = 0;
|
|
882
|
+
let received = 0;
|
|
883
|
+
while (true) {
|
|
884
|
+
const at = index * hashBytes;
|
|
885
|
+
const chunk = yield* body.read(at, hashBytes);
|
|
886
|
+
if (chunk.length === 0)
|
|
887
|
+
break;
|
|
888
|
+
if (index === 0) {
|
|
889
|
+
// Decide the spill once the first chunk is in: a body that
|
|
890
|
+
// ended within the in-memory threshold stays in memory.
|
|
891
|
+
const ended = spill.feeder.source.ended();
|
|
892
|
+
if (!(ended && spill.feeder.source.size <= spill.threshold)) {
|
|
893
|
+
upload = yield* spill.blobs.multipart(spill.key).pipe(Effect.mapError((error) => new PackIngestError({
|
|
894
|
+
reason: `spill: ${error.reason}`,
|
|
895
|
+
})), Effect.provide(RuntimeContext.phantom));
|
|
896
|
+
spill.feeder.expectFallback();
|
|
897
|
+
spilling = true;
|
|
898
|
+
}
|
|
899
|
+
}
|
|
900
|
+
const skip = index === 0 ? packStart + 12 : 0;
|
|
901
|
+
feed(index === 0 ? chunk.subarray(packStart) : chunk);
|
|
902
|
+
const base = at - packStart;
|
|
903
|
+
const fiber = yield* dispatch(chunk, {
|
|
904
|
+
base: base + skip,
|
|
905
|
+
skip,
|
|
906
|
+
resync: index > 0,
|
|
907
|
+
partNumber: Math.floor(at / partBytes) + 1,
|
|
908
|
+
});
|
|
909
|
+
console.log(`[pump] chunk ${index + 1} read at +${Date.now() - pumpStarted}ms (${chunk.length} bytes)`);
|
|
910
|
+
chunks.push({ index, base, payload: chunk, fiber });
|
|
911
|
+
index += 1;
|
|
912
|
+
received = at + chunk.length;
|
|
913
|
+
notifyConsumer();
|
|
914
|
+
body.release?.(received);
|
|
915
|
+
if (!hasher.writesSpill && received % partBytes === 0) {
|
|
916
|
+
yield* uploadPart(received);
|
|
917
|
+
}
|
|
918
|
+
if (chunk.length < hashBytes)
|
|
919
|
+
break;
|
|
920
|
+
}
|
|
921
|
+
if (!hasher.writesSpill)
|
|
922
|
+
yield* uploadPart(received);
|
|
923
|
+
}).pipe(Effect.ensuring(Effect.sync(() => {
|
|
924
|
+
producerDone = true;
|
|
925
|
+
notifyConsumer();
|
|
926
|
+
})));
|
|
927
|
+
// ── phase 2 (consumer): settle results in chunk order ──────────
|
|
928
|
+
// `prevEnd` is the last settled boundary. A chunk's resync result
|
|
929
|
+
// covers [firstOffset, …); whatever lies in [prevEnd, firstOffset)
|
|
930
|
+
// — usually one straddling entry, but any number when chunks are
|
|
931
|
+
// tiny — is scanned sequentially as one region from the retained
|
|
932
|
+
// payloads. Entries the region scan reaches at or past
|
|
933
|
+
// `firstOffset` are duplicates of the chunk's own result and are
|
|
934
|
+
// dropped; a region that does not end exactly at `firstOffset`
|
|
935
|
+
// means the resync was a false positive, and the chunk is rescanned
|
|
936
|
+
// sequentially from `prevEnd` instead.
|
|
937
|
+
const keepBelow = (result, limit) => {
|
|
938
|
+
const entries = result.entries.filter((e) => e.offset < limit);
|
|
939
|
+
const unresolved = result.unresolved.filter((u) => u.offset < limit);
|
|
940
|
+
// The settled boundary is the END of the last kept entry — which
|
|
941
|
+
// may lie past `limit` when that entry straddles a chunk edge.
|
|
942
|
+
let end = result.count === 0 ? result.consumedTo : -1;
|
|
943
|
+
for (const e of entries)
|
|
944
|
+
end = Math.max(end, e.dataOffset + e.span);
|
|
945
|
+
for (const u of unresolved)
|
|
946
|
+
end = Math.max(end, u.dataOffset + u.span);
|
|
947
|
+
return {
|
|
948
|
+
firstOffset: result.firstOffset,
|
|
949
|
+
entries,
|
|
950
|
+
unresolved,
|
|
951
|
+
consumedTo: end < 0 ? result.consumedTo : end,
|
|
952
|
+
count: entries.length + unresolved.length,
|
|
953
|
+
};
|
|
954
|
+
};
|
|
955
|
+
const trace = process.env.GIT_PUMP_DEBUG === "1"
|
|
956
|
+
? (...args) => console.log("[pump]", ...args)
|
|
957
|
+
: () => { };
|
|
958
|
+
const speculate = (start) => Effect.gen(function* () {
|
|
959
|
+
const head = bytesFrom(start, Math.min(start + 32, availableEnd()));
|
|
960
|
+
let need = start + 64;
|
|
961
|
+
try {
|
|
962
|
+
const h = decodeTypeSize(head, 0);
|
|
963
|
+
// zlib's worst case is ~0.1% + a few bytes; deltas carry an
|
|
964
|
+
// offset varint before their stream.
|
|
965
|
+
need = start + h.next + Math.ceil(h.size * 1.001) + 80;
|
|
966
|
+
}
|
|
967
|
+
catch {
|
|
968
|
+
// Header cut by the received edge: wait for more below.
|
|
969
|
+
}
|
|
970
|
+
while (true) {
|
|
971
|
+
const end = Math.min(need, availableEnd());
|
|
972
|
+
const bytes = bytesFrom(start, end);
|
|
973
|
+
const r = yield* hasher
|
|
974
|
+
.hashPart(bytes, {
|
|
975
|
+
base: start,
|
|
976
|
+
remaining: 1,
|
|
977
|
+
maxObjectSize: MAX_OBJECT_SIZE,
|
|
978
|
+
})
|
|
979
|
+
.pipe(Effect.mapError(asIngest));
|
|
980
|
+
if (r.count === 1)
|
|
981
|
+
return { bytes, r };
|
|
982
|
+
if (producerDone && end >= availableEnd())
|
|
983
|
+
return { bytes, r };
|
|
984
|
+
// Not complete in what has arrived: wait for another part.
|
|
985
|
+
if (end >= availableEnd())
|
|
986
|
+
yield* awaitChunk(chunks.length);
|
|
987
|
+
if (end >= need)
|
|
988
|
+
need = availableEnd();
|
|
989
|
+
}
|
|
990
|
+
});
|
|
991
|
+
const consume = Effect.gen(function* () {
|
|
992
|
+
let staged = 0;
|
|
993
|
+
let prevEnd = 12;
|
|
994
|
+
let speculative;
|
|
995
|
+
for (let k = 0;; k++) {
|
|
996
|
+
yield* awaitChunk(k);
|
|
997
|
+
if (k >= chunks.length)
|
|
998
|
+
break;
|
|
999
|
+
const current = chunks[k];
|
|
1000
|
+
const result = yield* Fiber.join(current.fiber);
|
|
1001
|
+
console.log(`[pump] chunk ${k + 1} settled at +${Date.now() - pumpStarted}ms`);
|
|
1002
|
+
if (result.part !== undefined) {
|
|
1003
|
+
parts.push(result.part.pipe(Effect.mapError(asIngest)));
|
|
1004
|
+
}
|
|
1005
|
+
const chunkEnd = current.base + current.payload.length;
|
|
1006
|
+
trace(`chunk ${k} base=${current.base} len=${current.payload.length} first=${result.firstOffset} consumedTo=${result.consumedTo} count=${result.count} prevEnd=${prevEnd} staged=${staged}`);
|
|
1007
|
+
const sequential = () => Effect.gen(function* () {
|
|
1008
|
+
// Everything from the settled boundary through this chunk,
|
|
1009
|
+
// scanned in order (plus a little of the next chunk so the last
|
|
1010
|
+
// entry can complete, if there is one).
|
|
1011
|
+
yield* awaitChunk(k + 1);
|
|
1012
|
+
const next = chunks[k + 1];
|
|
1013
|
+
const to = next === undefined
|
|
1014
|
+
? chunkEnd
|
|
1015
|
+
: Math.min(chunkEnd + 64, next.base + next.payload.length);
|
|
1016
|
+
const bytes = bytesFrom(prevEnd, to);
|
|
1017
|
+
const r = yield* hasher
|
|
1018
|
+
.hashPart(bytes, {
|
|
1019
|
+
base: prevEnd,
|
|
1020
|
+
remaining: count - staged,
|
|
1021
|
+
maxObjectSize: MAX_OBJECT_SIZE,
|
|
1022
|
+
})
|
|
1023
|
+
.pipe(Effect.mapError(asIngest));
|
|
1024
|
+
return { bytes, base: prevEnd, r: keepBelow(r, chunkEnd) };
|
|
1025
|
+
});
|
|
1026
|
+
if (result.firstOffset < 0) {
|
|
1027
|
+
// No boundary in this chunk (tiny, or inside one huge entry):
|
|
1028
|
+
// its bytes are settled by the pending straddler or a later
|
|
1029
|
+
// chunk's region scan.
|
|
1030
|
+
continue;
|
|
1031
|
+
}
|
|
1032
|
+
if (speculative !== undefined) {
|
|
1033
|
+
const sp = yield* Fiber.join(speculative.fiber);
|
|
1034
|
+
const start = speculative.start;
|
|
1035
|
+
speculative = undefined;
|
|
1036
|
+
if (sp.r.count === 1 &&
|
|
1037
|
+
start === prevEnd &&
|
|
1038
|
+
sp.r.consumedTo <= result.firstOffset) {
|
|
1039
|
+
staged += yield* stageResult(sp.bytes, start, sp.r);
|
|
1040
|
+
prevEnd = sp.r.consumedTo;
|
|
1041
|
+
}
|
|
1042
|
+
// Otherwise the boundary is suspect: the paths below rescan.
|
|
1043
|
+
}
|
|
1044
|
+
if (k === 0 && result.firstOffset !== 12) {
|
|
1045
|
+
const again = yield* sequential();
|
|
1046
|
+
staged += yield* stageResult(again.bytes, again.base, again.r);
|
|
1047
|
+
prevEnd = again.r.consumedTo;
|
|
1048
|
+
continue;
|
|
1049
|
+
}
|
|
1050
|
+
if (result.firstOffset < prevEnd) {
|
|
1051
|
+
// Resync landed inside an already-settled entry: rescan.
|
|
1052
|
+
const again = yield* sequential();
|
|
1053
|
+
staged += yield* stageResult(again.bytes, again.base, again.r);
|
|
1054
|
+
prevEnd = again.r.consumedTo;
|
|
1055
|
+
continue;
|
|
1056
|
+
}
|
|
1057
|
+
if (result.firstOffset > prevEnd) {
|
|
1058
|
+
trace(` region [${prevEnd}, ${result.firstOffset})`);
|
|
1059
|
+
regionCalls += 1;
|
|
1060
|
+
const region = bytesFrom(prevEnd, Math.min(result.firstOffset + 64, chunkEnd));
|
|
1061
|
+
const scanned = yield* hasher
|
|
1062
|
+
.hashPart(region, {
|
|
1063
|
+
base: prevEnd,
|
|
1064
|
+
remaining: count - staged,
|
|
1065
|
+
maxObjectSize: MAX_OBJECT_SIZE,
|
|
1066
|
+
})
|
|
1067
|
+
.pipe(Effect.mapError(asIngest));
|
|
1068
|
+
const ends = scanned.entries.some((e) => e.dataOffset + e.span === result.firstOffset) ||
|
|
1069
|
+
scanned.unresolved.some((u) => u.dataOffset + u.span === result.firstOffset);
|
|
1070
|
+
trace(` region scan count=${scanned.count} consumedTo=${scanned.consumedTo} ends=${ends}`);
|
|
1071
|
+
if (!ends) {
|
|
1072
|
+
trace(` → sequential fallback`);
|
|
1073
|
+
const again = yield* sequential();
|
|
1074
|
+
staged += yield* stageResult(again.bytes, again.base, again.r);
|
|
1075
|
+
prevEnd = again.r.consumedTo;
|
|
1076
|
+
continue;
|
|
1077
|
+
}
|
|
1078
|
+
staged += yield* stageResult(region, prevEnd, keepBelow(scanned, result.firstOffset));
|
|
1079
|
+
}
|
|
1080
|
+
staged += yield* stageResult(current.payload, current.base, result);
|
|
1081
|
+
prevEnd = result.consumedTo;
|
|
1082
|
+
if (prevEnd < chunkEnd && staged < count) {
|
|
1083
|
+
const start = prevEnd;
|
|
1084
|
+
speculative = {
|
|
1085
|
+
start,
|
|
1086
|
+
fiber: yield* Effect.forkChild(speculate(start)),
|
|
1087
|
+
};
|
|
1088
|
+
}
|
|
1089
|
+
}
|
|
1090
|
+
// A straddler still pending at the end (the last parts held no
|
|
1091
|
+
// boundary): settle it before the tail scan.
|
|
1092
|
+
if (speculative !== undefined) {
|
|
1093
|
+
const sp = yield* Fiber.join(speculative.fiber);
|
|
1094
|
+
const start = speculative.start;
|
|
1095
|
+
speculative = undefined;
|
|
1096
|
+
if (sp.r.count === 1 && start === prevEnd) {
|
|
1097
|
+
staged += yield* stageResult(sp.bytes, start, sp.r);
|
|
1098
|
+
prevEnd = sp.r.consumedTo;
|
|
1099
|
+
}
|
|
1100
|
+
}
|
|
1101
|
+
return { staged, prevEnd };
|
|
1102
|
+
});
|
|
1103
|
+
const consumer = yield* Effect.forkChild(consume);
|
|
1104
|
+
yield* produce;
|
|
1105
|
+
console.log(`[pump] body ended at +${Date.now() - pumpStarted}ms`);
|
|
1106
|
+
phases.upload = Date.now() - pumpStarted;
|
|
1107
|
+
let { staged, prevEnd } = yield* Fiber.join(consumer);
|
|
1108
|
+
// The tail: chunks too small to hold two whole entries report no
|
|
1109
|
+
// boundary, so entries after the last settled boundary may remain.
|
|
1110
|
+
// Scan that final region sequentially (it ends at the trailer).
|
|
1111
|
+
if (staged < count) {
|
|
1112
|
+
const last = chunks[chunks.length - 1];
|
|
1113
|
+
if (last !== undefined) {
|
|
1114
|
+
const to = last.base + last.payload.length;
|
|
1115
|
+
if (to > prevEnd) {
|
|
1116
|
+
const bytes = bytesFrom(prevEnd, to);
|
|
1117
|
+
const r = yield* hasher
|
|
1118
|
+
.hashPart(bytes, {
|
|
1119
|
+
base: prevEnd,
|
|
1120
|
+
remaining: count - staged,
|
|
1121
|
+
maxObjectSize: MAX_OBJECT_SIZE,
|
|
1122
|
+
})
|
|
1123
|
+
.pipe(Effect.mapError(asIngest));
|
|
1124
|
+
staged += yield* stageResult(bytes, prevEnd, r);
|
|
1125
|
+
prevEnd = r.consumedTo;
|
|
1126
|
+
}
|
|
1127
|
+
}
|
|
1128
|
+
}
|
|
1129
|
+
const consumedTo = prevEnd;
|
|
1130
|
+
phases.scan = Date.now() - pumpStarted;
|
|
1131
|
+
phases.chunks = chunks.length;
|
|
1132
|
+
phases.regions = regionCalls;
|
|
1133
|
+
if (staged !== count) {
|
|
1134
|
+
return yield* new PackIngestError({
|
|
1135
|
+
reason: `pack declared ${count} entries, scanned ${staged}`,
|
|
1136
|
+
});
|
|
1137
|
+
}
|
|
1138
|
+
const total = source.awaitEnd === undefined
|
|
1139
|
+
? source.size
|
|
1140
|
+
: yield* source.awaitEnd.pipe(Effect.mapError(asIngest));
|
|
1141
|
+
if (consumedTo !== total - 20) {
|
|
1142
|
+
return yield* new PackIngestError({
|
|
1143
|
+
reason: `pack has ${total - 20 - consumedTo} unconsumed bytes after ${count} entries`,
|
|
1144
|
+
});
|
|
1145
|
+
}
|
|
1146
|
+
// Everything read so far went through `feed`; the last part's
|
|
1147
|
+
// bytes did too, so the lag now holds the trailer.
|
|
1148
|
+
if (lag.length !== 20) {
|
|
1149
|
+
return yield* new PackIngestError({
|
|
1150
|
+
reason: "truncated pack trailer",
|
|
1151
|
+
});
|
|
1152
|
+
}
|
|
1153
|
+
const expected = bytesToHex(lag);
|
|
1154
|
+
const actual = trailerSha.digestHex();
|
|
1155
|
+
if (expected !== actual) {
|
|
1156
|
+
return yield* new PackIngestError({
|
|
1157
|
+
reason: `pack checksum mismatch: expected ${expected}, got ${actual}`,
|
|
1158
|
+
});
|
|
1159
|
+
}
|
|
1160
|
+
// Cross-part and thin deltas: bases are in the retained payloads
|
|
1161
|
+
// (or in the live store). Fixpoint for chains.
|
|
1162
|
+
const deltasStarted = Date.now();
|
|
1163
|
+
phases.unresolved = unresolved.length;
|
|
1164
|
+
// The resolved pack (DESIGN §22.13): every delta-resolved blob's
|
|
1165
|
+
// fresh zlib, `typeSize header + zdata` per entry, one object; rows
|
|
1166
|
+
// point at their zdata like promoted wire-pack rows do. Written in
|
|
1167
|
+
// two parts so the in-chunk resolutions — most of them — upload
|
|
1168
|
+
// while the cross-chunk rounds run.
|
|
1169
|
+
const writeResolvedPack = (suffix) => Effect.gen(function* () {
|
|
1170
|
+
if (resolvedBlobs.length === 0 || spill === undefined)
|
|
1171
|
+
return;
|
|
1172
|
+
const packId = `${spill.packId}${suffix}`;
|
|
1173
|
+
const key = packKeyOf(spill.repoId, packId);
|
|
1174
|
+
const pieces = [];
|
|
1175
|
+
const rows = [];
|
|
1176
|
+
let cursor = 0;
|
|
1177
|
+
for (const entry of resolvedBlobs) {
|
|
1178
|
+
const header = encodeTypeSize(entry.type, entry.size);
|
|
1179
|
+
pieces.push(header, entry.zdata);
|
|
1180
|
+
rows.push({
|
|
1181
|
+
...entry,
|
|
1182
|
+
pack: { packId, offset: cursor + header.length },
|
|
1183
|
+
});
|
|
1184
|
+
cursor += header.length + entry.zdata.byteLength;
|
|
1185
|
+
}
|
|
1186
|
+
resolvedBlobs.length = 0;
|
|
1187
|
+
const bytes = concatBytes(pieces);
|
|
1188
|
+
const writeStarted = Date.now();
|
|
1189
|
+
const writing = yield* Effect.forkDetach(spill.blobs.put(key, bytes).pipe(Effect.mapError((error) => new PackIngestError({
|
|
1190
|
+
reason: `resolved pack: ${error.reason}`,
|
|
1191
|
+
})), Effect.provide(RuntimeContext.phantom)));
|
|
1192
|
+
resolvedKeys.push(key);
|
|
1193
|
+
resolvedKey = resolvedKeys.join(",");
|
|
1194
|
+
phases.resolvedBytes = (phases.resolvedBytes ?? 0) + bytes.length;
|
|
1195
|
+
yield* stage(rows);
|
|
1196
|
+
return { writing, writeStarted };
|
|
1197
|
+
});
|
|
1198
|
+
const early = yield* writeResolvedPack("-r");
|
|
1199
|
+
const spanOf = (at, length) => Effect.suspend(() => {
|
|
1200
|
+
const bytes = readSpan?.(at, length);
|
|
1201
|
+
return bytes === undefined
|
|
1202
|
+
? source.read(at, length)
|
|
1203
|
+
: Effect.succeed(bytes);
|
|
1204
|
+
});
|
|
1205
|
+
const inflateSpan = (item) => item.content !== undefined
|
|
1206
|
+
? Effect.succeed(item.content)
|
|
1207
|
+
: item.zdata !== undefined
|
|
1208
|
+
? Zlib.inflate(item.zdata).pipe(Effect.mapError(asIngest))
|
|
1209
|
+
: spanOf(item.dataOffset, item.span).pipe(Effect.flatMap((z) => Zlib.inflate(z)), Effect.mapError(asIngest));
|
|
1210
|
+
// Rounds (DESIGN §22.13): every delta whose base is known goes into
|
|
1211
|
+
// byte-bounded batches the hasher resolves in parallel (its bases
|
|
1212
|
+
// shipped once per batch); a delta on a still-unresolved delta waits
|
|
1213
|
+
// for the next round. The receiver only assembles bytes it already
|
|
1214
|
+
// holds.
|
|
1215
|
+
const batchBudget = hasher.chunkBytes ?? HASH_PART_BYTES;
|
|
1216
|
+
const baseBytesOf = (item) => Effect.gen(function* () {
|
|
1217
|
+
if (item.content !== undefined) {
|
|
1218
|
+
return { bytes: item.content, isContent: true };
|
|
1219
|
+
}
|
|
1220
|
+
if (item.zdata !== undefined) {
|
|
1221
|
+
return { bytes: item.zdata, isContent: false };
|
|
1222
|
+
}
|
|
1223
|
+
return {
|
|
1224
|
+
bytes: yield* spanOf(item.dataOffset, item.span),
|
|
1225
|
+
isContent: false,
|
|
1226
|
+
};
|
|
1227
|
+
});
|
|
1228
|
+
let pending = unresolved;
|
|
1229
|
+
while (pending.length > 0) {
|
|
1230
|
+
const next = [];
|
|
1231
|
+
const ready = [];
|
|
1232
|
+
for (const u of pending) {
|
|
1233
|
+
let base = u.baseOffset !== undefined ? known.get(u.baseOffset) : undefined;
|
|
1234
|
+
if (base === undefined && u.baseOid !== undefined) {
|
|
1235
|
+
base = knownByOid.get(u.baseOid);
|
|
1236
|
+
if (base === undefined) {
|
|
1237
|
+
const live = yield* store.readBase(u.baseOid);
|
|
1238
|
+
if (live !== undefined) {
|
|
1239
|
+
base = {
|
|
1240
|
+
oid: u.baseOid,
|
|
1241
|
+
type: live.type,
|
|
1242
|
+
dataOffset: -1,
|
|
1243
|
+
span: 0,
|
|
1244
|
+
content: live.content,
|
|
1245
|
+
};
|
|
1246
|
+
knownByOid.set(u.baseOid, base);
|
|
1247
|
+
}
|
|
1248
|
+
}
|
|
1249
|
+
}
|
|
1250
|
+
if (base === undefined) {
|
|
1251
|
+
next.push(u);
|
|
1252
|
+
continue;
|
|
1253
|
+
}
|
|
1254
|
+
ready.push({
|
|
1255
|
+
u,
|
|
1256
|
+
base,
|
|
1257
|
+
baseKey: base.dataOffset >= 0
|
|
1258
|
+
? `o:${base.dataOffset}`
|
|
1259
|
+
: `oid:${base.oid}`,
|
|
1260
|
+
});
|
|
1261
|
+
}
|
|
1262
|
+
if (ready.length === 0) {
|
|
1263
|
+
return yield* new PackIngestError({
|
|
1264
|
+
reason: `delta base not found for ${next.length} entries`,
|
|
1265
|
+
});
|
|
1266
|
+
}
|
|
1267
|
+
const batches = [];
|
|
1268
|
+
let current;
|
|
1269
|
+
for (const r of ready) {
|
|
1270
|
+
const delta = yield* spanOf(r.u.dataOffset, r.u.span);
|
|
1271
|
+
const baseBytes = yield* baseBytesOf(r.base);
|
|
1272
|
+
const baseCost = current?.index.has(r.baseKey)
|
|
1273
|
+
? 0
|
|
1274
|
+
: baseBytes.bytes.length;
|
|
1275
|
+
if (current === undefined ||
|
|
1276
|
+
(current.jobs.length > 0 &&
|
|
1277
|
+
current.bytes + delta.length + baseCost > batchBudget)) {
|
|
1278
|
+
current = {
|
|
1279
|
+
bases: [],
|
|
1280
|
+
index: new Map(),
|
|
1281
|
+
jobs: [],
|
|
1282
|
+
items: [],
|
|
1283
|
+
bytes: 0,
|
|
1284
|
+
};
|
|
1285
|
+
batches.push(current);
|
|
1286
|
+
}
|
|
1287
|
+
let baseIndex = current.index.get(r.baseKey);
|
|
1288
|
+
if (baseIndex === undefined) {
|
|
1289
|
+
baseIndex = current.bases.push(baseBytes) - 1;
|
|
1290
|
+
current.index.set(r.baseKey, baseIndex);
|
|
1291
|
+
current.bytes += baseBytes.bytes.length;
|
|
1292
|
+
}
|
|
1293
|
+
current.jobs.push({
|
|
1294
|
+
id: current.jobs.length,
|
|
1295
|
+
type: r.base.type,
|
|
1296
|
+
base: baseIndex,
|
|
1297
|
+
delta,
|
|
1298
|
+
});
|
|
1299
|
+
current.items.push(r);
|
|
1300
|
+
current.bytes += delta.length;
|
|
1301
|
+
}
|
|
1302
|
+
const resolved = yield* Effect.all(batches.map((batch) => hasher
|
|
1303
|
+
.resolveDeltas(batch.bases, batch.jobs, {
|
|
1304
|
+
maxObjectSize: MAX_OBJECT_SIZE,
|
|
1305
|
+
})
|
|
1306
|
+
.pipe(Effect.catchTag("HashError", (error) => {
|
|
1307
|
+
console.warn(`[pump] ${error.reason}; resolving inline`);
|
|
1308
|
+
return PartialScan.resolveDeltas(batch.bases, batch.jobs, {
|
|
1309
|
+
maxObjectSize: MAX_OBJECT_SIZE,
|
|
1310
|
+
});
|
|
1311
|
+
}), Effect.mapError(asIngest), Effect.map((results) => ({ batch, results })))), { concurrency: hasher.concurrency ?? HASH_CONCURRENCY });
|
|
1312
|
+
for (const { batch, results } of resolved) {
|
|
1313
|
+
const incoming = [];
|
|
1314
|
+
for (const result of results) {
|
|
1315
|
+
const r = batch.items[result.id];
|
|
1316
|
+
const item = {
|
|
1317
|
+
oid: result.oid,
|
|
1318
|
+
type: r.base.type,
|
|
1319
|
+
dataOffset: r.u.dataOffset,
|
|
1320
|
+
span: r.u.span,
|
|
1321
|
+
zdata: result.zdata,
|
|
1322
|
+
content: result.content,
|
|
1323
|
+
};
|
|
1324
|
+
known.set(r.u.offset, item);
|
|
1325
|
+
knownByOid.set(result.oid, item);
|
|
1326
|
+
incoming.push({
|
|
1327
|
+
oid: result.oid,
|
|
1328
|
+
type: r.base.type,
|
|
1329
|
+
size: result.size,
|
|
1330
|
+
zdata: result.zdata,
|
|
1331
|
+
span: r.u.span,
|
|
1332
|
+
dataOffset: r.u.dataOffset,
|
|
1333
|
+
fromDelta: true,
|
|
1334
|
+
content: result.content,
|
|
1335
|
+
});
|
|
1336
|
+
}
|
|
1337
|
+
yield* stage(incoming);
|
|
1338
|
+
}
|
|
1339
|
+
pending = next;
|
|
1340
|
+
}
|
|
1341
|
+
phases.deltas = Date.now() - deltasStarted;
|
|
1342
|
+
const late = yield* writeResolvedPack("-r2");
|
|
1343
|
+
yield* flush();
|
|
1344
|
+
for (const pending of [early, late]) {
|
|
1345
|
+
if (pending === undefined)
|
|
1346
|
+
continue;
|
|
1347
|
+
yield* Fiber.join(pending.writing);
|
|
1348
|
+
phases.resolvedPack = Math.max(phases.resolvedPack ?? 0, Date.now() - pending.writeStarted);
|
|
1349
|
+
}
|
|
1350
|
+
// Settle the spill: every part was written by its hasher; complete
|
|
1351
|
+
// the object and hand it to the source as the fallback reader.
|
|
1352
|
+
if (upload !== undefined && spill !== undefined) {
|
|
1353
|
+
const settled = upload;
|
|
1354
|
+
const uploaded = [];
|
|
1355
|
+
for (const part of parts)
|
|
1356
|
+
uploaded.push(yield* part);
|
|
1357
|
+
yield* settled.complete(uploaded).pipe(Effect.mapError((error) => new PackIngestError({
|
|
1358
|
+
reason: `spill complete: ${error.reason}`,
|
|
1359
|
+
})), Effect.provide(RuntimeContext.phantom));
|
|
1360
|
+
spill.feeder.setFallback(blobRandomAccess({
|
|
1361
|
+
blobs: spill.blobs,
|
|
1362
|
+
key: spill.key,
|
|
1363
|
+
size: yield* spill.feeder.source.awaitEnd.pipe(Effect.mapError(asIngest)),
|
|
1364
|
+
}));
|
|
1365
|
+
parkedKey = spill.key;
|
|
1366
|
+
}
|
|
1367
|
+
return { count };
|
|
1368
|
+
}).pipe(
|
|
1369
|
+
// A failed ingest must not leave a dangling multipart upload —
|
|
1370
|
+
// R2 bills incomplete uploads until aborted or lifecycle-expired.
|
|
1371
|
+
Effect.onError(() => Effect.suspend(() => upload === undefined || parkedKey !== undefined
|
|
1372
|
+
? Effect.void
|
|
1373
|
+
: upload.abort.pipe(Effect.provide(RuntimeContext.phantom))).pipe(Effect.ignore)), Effect.onError(() => Effect.suspend(() => resolvedKeys.length === 0 || options.spill === undefined
|
|
1374
|
+
? Effect.void
|
|
1375
|
+
: options.spill.blobs
|
|
1376
|
+
.delete([...resolvedKeys])
|
|
1377
|
+
.pipe(Effect.provide(RuntimeContext.phantom))).pipe(Effect.ignore)));
|
|
1378
|
+
const summary = options.hasher !== undefined
|
|
1379
|
+
? yield* pumpThroughHasher(options.hasher)
|
|
1380
|
+
: yield* PackParser.ingestPack({
|
|
1381
|
+
source,
|
|
1382
|
+
store,
|
|
1383
|
+
maxObjectSize: MAX_OBJECT_SIZE,
|
|
1384
|
+
phases,
|
|
1385
|
+
sink: (entry) => stage([entry]),
|
|
1386
|
+
sinkBatch: stage,
|
|
1387
|
+
}).pipe(Effect.mapError((error) => error._tag === "StoreError" || error._tag === "PackIngestError"
|
|
1388
|
+
? error
|
|
1389
|
+
: new PackIngestError({ reason: packParserReason(error) })));
|
|
1390
|
+
yield* flush();
|
|
1391
|
+
if (store.settle !== undefined) {
|
|
1392
|
+
const at = yield* Effect.sync(() => performance.now());
|
|
1393
|
+
yield* store.settle;
|
|
1394
|
+
stageMs += yield* Effect.sync(() => performance.now() - at);
|
|
1395
|
+
}
|
|
1396
|
+
return {
|
|
1397
|
+
stageMs,
|
|
1398
|
+
phases,
|
|
1399
|
+
promoted,
|
|
1400
|
+
parkedKey,
|
|
1401
|
+
resolvedKey,
|
|
1402
|
+
objectCount: summary.count,
|
|
1403
|
+
// The parser verifies the trailer itself; the checksum is not used
|
|
1404
|
+
// downstream, so it is not re-derived here.
|
|
1405
|
+
packSha: "",
|
|
1406
|
+
commits,
|
|
1407
|
+
// The connectivity check (DESIGN §22.14) needs only the edges that
|
|
1408
|
+
// leave the push: everything staged here is known present.
|
|
1409
|
+
referenced: Array.from(referenced).filter((oid) => !stagedOids.has(oid)),
|
|
1410
|
+
referencedParents: Array.from(referencedParents).filter((oid) => !stagedOids.has(oid)),
|
|
1411
|
+
};
|
|
1412
|
+
});
|
|
1413
|
+
/** Renders a `PackParser` failure as an in-band `unpack <reason>` string. */
|
|
1414
|
+
const packParserReason = (error) => {
|
|
1415
|
+
switch (error._tag) {
|
|
1416
|
+
case "PackChecksumMismatch":
|
|
1417
|
+
return "pack checksum mismatch";
|
|
1418
|
+
case "MissingDeltaBaseError":
|
|
1419
|
+
return `missing delta base ${error.baseOid ?? ""}`.trim();
|
|
1420
|
+
case "ObjectTooLargeError":
|
|
1421
|
+
return `object too large (${error.size ?? 0} > ${error.limit ?? 0})`;
|
|
1422
|
+
default:
|
|
1423
|
+
return error.reason ?? error._tag;
|
|
1424
|
+
}
|
|
1425
|
+
};
|
|
1426
|
+
export const ingestPack = (pack, options) => Effect.gen(function* () {
|
|
1427
|
+
const { store, pushId } = options;
|
|
1428
|
+
if (pack.length < 12 + 20) {
|
|
1429
|
+
return yield* new PackIngestError({ reason: "pack too small" });
|
|
1430
|
+
}
|
|
1431
|
+
if (pack[0] !== 0x50 ||
|
|
1432
|
+
pack[1] !== 0x41 ||
|
|
1433
|
+
pack[2] !== 0x43 ||
|
|
1434
|
+
pack[3] !== 0x4b) {
|
|
1435
|
+
return yield* new PackIngestError({ reason: "bad pack signature" });
|
|
1436
|
+
}
|
|
1437
|
+
const view = new DataView(pack.buffer, pack.byteOffset, pack.byteLength);
|
|
1438
|
+
const version = view.getUint32(4);
|
|
1439
|
+
if (version !== 2) {
|
|
1440
|
+
return yield* new PackIngestError({
|
|
1441
|
+
reason: `unsupported pack version ${version}`,
|
|
1442
|
+
});
|
|
1443
|
+
}
|
|
1444
|
+
const count = view.getUint32(8);
|
|
1445
|
+
// Trailer verification first — cheap, and everything after assumes an
|
|
1446
|
+
// intact buffer.
|
|
1447
|
+
const trailer = bytesToHex(pack.subarray(pack.length - 20));
|
|
1448
|
+
const sha = makeSha1();
|
|
1449
|
+
sha.update(pack.subarray(0, pack.length - 20));
|
|
1450
|
+
const actual = sha.digestHex();
|
|
1451
|
+
if (actual !== trailer) {
|
|
1452
|
+
return yield* new PackIngestError({ reason: "pack checksum mismatch" });
|
|
1453
|
+
}
|
|
1454
|
+
const cache = makeContentCache(CACHE_BUDGET);
|
|
1455
|
+
const entries = [];
|
|
1456
|
+
const byOffset = new Map();
|
|
1457
|
+
const byOid = new Map();
|
|
1458
|
+
const commits = [];
|
|
1459
|
+
const referenced = new Set();
|
|
1460
|
+
const referencedParents = new Set();
|
|
1461
|
+
/** Record graph facts + referenced edges for a resolved object. */
|
|
1462
|
+
const recordObject = Effect.fn(function* (oid, type, content) {
|
|
1463
|
+
switch (type) {
|
|
1464
|
+
case ObjectType.commit: {
|
|
1465
|
+
const parsed = yield* parseCommit(content).pipe(Effect.mapError((error) => new PackIngestError({
|
|
1466
|
+
reason: `bad commit ${oid}: ${error.reason}`,
|
|
1467
|
+
})));
|
|
1468
|
+
commits.push({
|
|
1469
|
+
oid,
|
|
1470
|
+
tree: parsed.tree,
|
|
1471
|
+
parents: parsed.parents,
|
|
1472
|
+
commitTime: parsed.committer.when,
|
|
1473
|
+
});
|
|
1474
|
+
referenced.add(parsed.tree);
|
|
1475
|
+
for (const parent of parsed.parents) {
|
|
1476
|
+
referencedParents.add(parent);
|
|
1477
|
+
}
|
|
1478
|
+
return;
|
|
1479
|
+
}
|
|
1480
|
+
case ObjectType.tree: {
|
|
1481
|
+
const parsed = yield* parseTree(content).pipe(Effect.mapError((error) => new PackIngestError({
|
|
1482
|
+
reason: `bad tree ${oid}: ${error.reason}`,
|
|
1483
|
+
})));
|
|
1484
|
+
for (const entry of parsed) {
|
|
1485
|
+
if (treeEntryKind(entry.mode) !== "commit") {
|
|
1486
|
+
referenced.add(entry.oid);
|
|
1487
|
+
}
|
|
1488
|
+
}
|
|
1489
|
+
return;
|
|
1490
|
+
}
|
|
1491
|
+
case ObjectType.tag: {
|
|
1492
|
+
const parsed = yield* parseTag(content).pipe(Effect.mapError((error) => new PackIngestError({
|
|
1493
|
+
reason: `bad tag ${oid}: ${error.reason}`,
|
|
1494
|
+
})));
|
|
1495
|
+
referenced.add(parsed.object);
|
|
1496
|
+
return;
|
|
1497
|
+
}
|
|
1498
|
+
case ObjectType.blob:
|
|
1499
|
+
return;
|
|
1500
|
+
}
|
|
1501
|
+
});
|
|
1502
|
+
const stage = Effect.fn(function* (oid, type, content, zdata) {
|
|
1503
|
+
const staged = {
|
|
1504
|
+
oid,
|
|
1505
|
+
type,
|
|
1506
|
+
size: content.length,
|
|
1507
|
+
zdata,
|
|
1508
|
+
};
|
|
1509
|
+
yield* store.insertStaged(pushId, staged);
|
|
1510
|
+
yield* recordObject(oid, type, content);
|
|
1511
|
+
});
|
|
1512
|
+
// ── Pass 1: scan entries, stage non-deltas verbatim ─────────────────────
|
|
1513
|
+
let offset = 12;
|
|
1514
|
+
const zlibToIngest = (error) => new PackIngestError({ reason: error.reason });
|
|
1515
|
+
for (let i = 0; i < count; i++) {
|
|
1516
|
+
const entryStart = offset;
|
|
1517
|
+
let header;
|
|
1518
|
+
try {
|
|
1519
|
+
header = decodeTypeSize(pack, offset);
|
|
1520
|
+
}
|
|
1521
|
+
catch (error) {
|
|
1522
|
+
return yield* new PackIngestError({
|
|
1523
|
+
reason: `entry ${i}: ${String(error)}`,
|
|
1524
|
+
});
|
|
1525
|
+
}
|
|
1526
|
+
if (!isDeltaType(header.type)) {
|
|
1527
|
+
if (header.size > MAX_OBJECT_SIZE) {
|
|
1528
|
+
return yield* new PackIngestError({ reason: "object too large" });
|
|
1529
|
+
}
|
|
1530
|
+
const inflated = yield* Zlib.inflateEntry(pack, header.next, {
|
|
1531
|
+
maxOutput: header.size,
|
|
1532
|
+
}).pipe(Effect.mapError(zlibToIngest));
|
|
1533
|
+
if (inflated.content.length !== header.size) {
|
|
1534
|
+
return yield* new PackIngestError({
|
|
1535
|
+
reason: `entry ${i}: size mismatch (${inflated.content.length} != ${header.size})`,
|
|
1536
|
+
});
|
|
1537
|
+
}
|
|
1538
|
+
const type = header.type;
|
|
1539
|
+
const oid = yield* hashObject(type, inflated.content);
|
|
1540
|
+
const zdata = pack.subarray(header.next, header.next + inflated.bytesConsumed);
|
|
1541
|
+
const entry = {
|
|
1542
|
+
offset: entryStart,
|
|
1543
|
+
kind: "object",
|
|
1544
|
+
type,
|
|
1545
|
+
declaredSize: header.size,
|
|
1546
|
+
zstart: header.next,
|
|
1547
|
+
zlen: inflated.bytesConsumed,
|
|
1548
|
+
baseOffset: undefined,
|
|
1549
|
+
baseOid: undefined,
|
|
1550
|
+
oid,
|
|
1551
|
+
resolvedType: type,
|
|
1552
|
+
};
|
|
1553
|
+
entries.push(entry);
|
|
1554
|
+
byOffset.set(entryStart, entry);
|
|
1555
|
+
byOid.set(oid, entry);
|
|
1556
|
+
cache.set(oid, inflated.content);
|
|
1557
|
+
yield* stage(oid, type, inflated.content, zdata);
|
|
1558
|
+
offset = header.next + inflated.bytesConsumed;
|
|
1559
|
+
}
|
|
1560
|
+
else {
|
|
1561
|
+
let zstart = header.next;
|
|
1562
|
+
let baseOffset;
|
|
1563
|
+
let baseOid;
|
|
1564
|
+
if (header.type === 6) {
|
|
1565
|
+
let decoded;
|
|
1566
|
+
try {
|
|
1567
|
+
decoded = decodeOfsDeltaOffset(pack, header.next);
|
|
1568
|
+
}
|
|
1569
|
+
catch (error) {
|
|
1570
|
+
return yield* new PackIngestError({
|
|
1571
|
+
reason: `entry ${i}: ${String(error)}`,
|
|
1572
|
+
});
|
|
1573
|
+
}
|
|
1574
|
+
baseOffset = entryStart - decoded.value;
|
|
1575
|
+
if (baseOffset < 12) {
|
|
1576
|
+
return yield* new PackIngestError({
|
|
1577
|
+
reason: `entry ${i}: ofs-delta base offset out of range`,
|
|
1578
|
+
});
|
|
1579
|
+
}
|
|
1580
|
+
zstart = decoded.next;
|
|
1581
|
+
}
|
|
1582
|
+
else {
|
|
1583
|
+
if (header.next + 20 > pack.length) {
|
|
1584
|
+
return yield* new PackIngestError({
|
|
1585
|
+
reason: `entry ${i}: truncated ref-delta base id`,
|
|
1586
|
+
});
|
|
1587
|
+
}
|
|
1588
|
+
baseOid = bytesToHex(pack.subarray(header.next, header.next + 20));
|
|
1589
|
+
zstart = header.next + 20;
|
|
1590
|
+
}
|
|
1591
|
+
const inflated = yield* Zlib.inflateEntry(pack, zstart, {
|
|
1592
|
+
maxOutput: header.size,
|
|
1593
|
+
}).pipe(Effect.mapError(zlibToIngest));
|
|
1594
|
+
const entry = {
|
|
1595
|
+
offset: entryStart,
|
|
1596
|
+
kind: header.type === 6 ? "ofs" : "ref",
|
|
1597
|
+
type: undefined,
|
|
1598
|
+
declaredSize: header.size,
|
|
1599
|
+
zstart,
|
|
1600
|
+
zlen: inflated.bytesConsumed,
|
|
1601
|
+
baseOffset,
|
|
1602
|
+
baseOid,
|
|
1603
|
+
oid: undefined,
|
|
1604
|
+
resolvedType: undefined,
|
|
1605
|
+
};
|
|
1606
|
+
entries.push(entry);
|
|
1607
|
+
byOffset.set(entryStart, entry);
|
|
1608
|
+
offset = zstart + inflated.bytesConsumed;
|
|
1609
|
+
}
|
|
1610
|
+
if (offset > pack.length - 20) {
|
|
1611
|
+
return yield* new PackIngestError({
|
|
1612
|
+
reason: `entry ${i}: pack truncated`,
|
|
1613
|
+
});
|
|
1614
|
+
}
|
|
1615
|
+
}
|
|
1616
|
+
if (offset !== pack.length - 20) {
|
|
1617
|
+
return yield* new PackIngestError({
|
|
1618
|
+
reason: "trailing garbage between entries and pack trailer",
|
|
1619
|
+
});
|
|
1620
|
+
}
|
|
1621
|
+
// ── Pass 2: resolve deltas (bases may chain; thin bases from store) ─────
|
|
1622
|
+
const contentOf = (entry, depth) => Effect.gen(function* () {
|
|
1623
|
+
if (depth > MAX_DELTA_DEPTH) {
|
|
1624
|
+
return yield* new PackIngestError({ reason: "delta chain too deep" });
|
|
1625
|
+
}
|
|
1626
|
+
if (entry.oid !== undefined && entry.resolvedType !== undefined) {
|
|
1627
|
+
const cached = cache.get(entry.oid);
|
|
1628
|
+
if (cached !== undefined) {
|
|
1629
|
+
return { content: cached, type: entry.resolvedType };
|
|
1630
|
+
}
|
|
1631
|
+
}
|
|
1632
|
+
if (entry.kind === "object") {
|
|
1633
|
+
const inflated = yield* Zlib.inflateEntry(pack, entry.zstart, {
|
|
1634
|
+
maxOutput: entry.declaredSize,
|
|
1635
|
+
}).pipe(Effect.mapError(zlibToIngest));
|
|
1636
|
+
if (entry.oid !== undefined)
|
|
1637
|
+
cache.set(entry.oid, inflated.content);
|
|
1638
|
+
return { content: inflated.content, type: entry.type };
|
|
1639
|
+
}
|
|
1640
|
+
// delta — resolve the base first
|
|
1641
|
+
const base = yield* Effect.gen(function* () {
|
|
1642
|
+
if (entry.kind === "ofs") {
|
|
1643
|
+
const baseEntry = byOffset.get(entry.baseOffset);
|
|
1644
|
+
if (baseEntry === undefined) {
|
|
1645
|
+
return yield* new PackIngestError({
|
|
1646
|
+
reason: "ofs-delta base is not an entry boundary",
|
|
1647
|
+
});
|
|
1648
|
+
}
|
|
1649
|
+
return yield* contentOf(baseEntry, depth + 1);
|
|
1650
|
+
}
|
|
1651
|
+
const inPack = byOid.get(entry.baseOid);
|
|
1652
|
+
if (inPack !== undefined) {
|
|
1653
|
+
return yield* contentOf(inPack, depth + 1);
|
|
1654
|
+
}
|
|
1655
|
+
// Thin base: must exist in the live store.
|
|
1656
|
+
const meta = yield* store.getMeta(entry.baseOid);
|
|
1657
|
+
if (meta === undefined) {
|
|
1658
|
+
return yield* new PackIngestError({
|
|
1659
|
+
reason: `missing thin-pack base ${entry.baseOid}`,
|
|
1660
|
+
});
|
|
1661
|
+
}
|
|
1662
|
+
if (meta.size > MAX_OBJECT_SIZE) {
|
|
1663
|
+
return yield* new PackIngestError({ reason: "object too large" });
|
|
1664
|
+
}
|
|
1665
|
+
const content = yield* store.readContent(entry.baseOid);
|
|
1666
|
+
cache.set(entry.baseOid, content);
|
|
1667
|
+
return { content, type: meta.type };
|
|
1668
|
+
});
|
|
1669
|
+
const delta = yield* Zlib.inflateEntry(pack, entry.zstart, {
|
|
1670
|
+
maxOutput: entry.declaredSize,
|
|
1671
|
+
}).pipe(Effect.mapError(zlibToIngest));
|
|
1672
|
+
const content = yield* applyDelta(base.content, delta.content).pipe(Effect.mapError((error) => new PackIngestError({ reason: error.reason })));
|
|
1673
|
+
if (content.length > MAX_OBJECT_SIZE) {
|
|
1674
|
+
return yield* new PackIngestError({ reason: "object too large" });
|
|
1675
|
+
}
|
|
1676
|
+
return { content, type: base.type };
|
|
1677
|
+
});
|
|
1678
|
+
for (const entry of entries) {
|
|
1679
|
+
if (entry.kind === "object" || entry.oid !== undefined)
|
|
1680
|
+
continue;
|
|
1681
|
+
const resolved = yield* contentOf(entry, 0);
|
|
1682
|
+
const oid = yield* hashObject(resolved.type, resolved.content);
|
|
1683
|
+
entry.oid = oid;
|
|
1684
|
+
entry.resolvedType = resolved.type;
|
|
1685
|
+
byOid.set(oid, entry);
|
|
1686
|
+
cache.set(oid, resolved.content);
|
|
1687
|
+
const zdata = yield* Zlib.deflate(resolved.content).pipe(Effect.mapError(zlibToIngest));
|
|
1688
|
+
yield* stage(oid, resolved.type, resolved.content, zdata);
|
|
1689
|
+
}
|
|
1690
|
+
return {
|
|
1691
|
+
objectCount: count,
|
|
1692
|
+
packSha: trailer,
|
|
1693
|
+
commits,
|
|
1694
|
+
referenced: Array.from(referenced),
|
|
1695
|
+
referencedParents: Array.from(referencedParents),
|
|
1696
|
+
};
|
|
1697
|
+
});
|
|
1698
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
1699
|
+
// Small shared helpers
|
|
1700
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
1701
|
+
const asOid = (s) => s;
|
|
1702
|
+
const heapBefore = (a, b) => a.gen !== b.gen ? a.gen > b.gen : a.time > b.time;
|
|
1703
|
+
/** Pushes onto a binary max-heap keyed `(gen desc, commit_time desc)`. */
|
|
1704
|
+
export const heapPush = (heap, node) => {
|
|
1705
|
+
heap.push(node);
|
|
1706
|
+
let i = heap.length - 1;
|
|
1707
|
+
while (i > 0) {
|
|
1708
|
+
const parent = (i - 1) >> 1;
|
|
1709
|
+
if (!heapBefore(heap[i], heap[parent]))
|
|
1710
|
+
break;
|
|
1711
|
+
const tmp = heap[parent];
|
|
1712
|
+
heap[parent] = heap[i];
|
|
1713
|
+
heap[i] = tmp;
|
|
1714
|
+
i = parent;
|
|
1715
|
+
}
|
|
1716
|
+
};
|
|
1717
|
+
/** Pops the max node. Callers must check `heap.length > 0` first. */
|
|
1718
|
+
export const heapPop = (heap) => {
|
|
1719
|
+
const top = heap[0];
|
|
1720
|
+
const last = heap.pop();
|
|
1721
|
+
if (heap.length > 0) {
|
|
1722
|
+
heap[0] = last;
|
|
1723
|
+
let i = 0;
|
|
1724
|
+
for (;;) {
|
|
1725
|
+
const left = 2 * i + 1;
|
|
1726
|
+
const right = left + 1;
|
|
1727
|
+
let max = i;
|
|
1728
|
+
if (left < heap.length && heapBefore(heap[left], heap[max])) {
|
|
1729
|
+
max = left;
|
|
1730
|
+
}
|
|
1731
|
+
if (right < heap.length && heapBefore(heap[right], heap[max])) {
|
|
1732
|
+
max = right;
|
|
1733
|
+
}
|
|
1734
|
+
if (max === i)
|
|
1735
|
+
break;
|
|
1736
|
+
const tmp = heap[max];
|
|
1737
|
+
heap[max] = heap[i];
|
|
1738
|
+
heap[i] = tmp;
|
|
1739
|
+
i = max;
|
|
1740
|
+
}
|
|
1741
|
+
}
|
|
1742
|
+
return top;
|
|
1743
|
+
};
|
|
1744
|
+
/** Decompresses a request body when it is gzip (header or 1f8b sniff). */
|
|
1745
|
+
export const gunzipIfNeeded = (body, contentEncoding) => {
|
|
1746
|
+
const looksGzip = body.length >= 2 && body[0] === 0x1f && body[1] === 0x8b;
|
|
1747
|
+
if (contentEncoding?.toLowerCase() !== "gzip" && !looksGzip) {
|
|
1748
|
+
return Effect.succeed(body);
|
|
1749
|
+
}
|
|
1750
|
+
if (!looksGzip) {
|
|
1751
|
+
// Content-Encoding claimed gzip but the magic disagrees — trust bytes.
|
|
1752
|
+
return Effect.succeed(body);
|
|
1753
|
+
}
|
|
1754
|
+
return Effect.tryPromise({
|
|
1755
|
+
try: () => new Response(new Response(body).body.pipeThrough(new DecompressionStream("gzip")))
|
|
1756
|
+
.arrayBuffer()
|
|
1757
|
+
.then((buffer) => new Uint8Array(buffer)),
|
|
1758
|
+
catch: (error) => new PackIngestError({ reason: `gzip decompression failed: ${error}` }),
|
|
1759
|
+
});
|
|
1760
|
+
};
|
|
1761
|
+
const noCache = { "cache-control": "no-cache" };
|
|
1762
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
1763
|
+
// The Durable Object
|
|
1764
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
1765
|
+
/**
|
|
1766
|
+
* The per-repo Durable Object class (modular form). The runtime
|
|
1767
|
+
* implementation is {@link GitRepoLive}; the hosting Worker provides it via
|
|
1768
|
+
* `Effect.provide(GitRepoLive)` and consumers `yield* GitRepo` for the
|
|
1769
|
+
* namespace handle.
|
|
1770
|
+
*/
|
|
1771
|
+
export class GitRepo extends Cloudflare.DurableObject()("GitRepo", {
|
|
1772
|
+
// Every tagged error the RPC surface can fail with: the calling Worker
|
|
1773
|
+
// reconstructs real class instances from the RPC wire (see the
|
|
1774
|
+
// `DurableObjectProps.errors` doc), so catchTag/instanceof/HttpApi
|
|
1775
|
+
// encoding all see the classes the DO actually failed with.
|
|
1776
|
+
errors: [
|
|
1777
|
+
ReadOnlyRepo,
|
|
1778
|
+
RepoNotFound,
|
|
1779
|
+
RefNotFound,
|
|
1780
|
+
RefConflict,
|
|
1781
|
+
ObjectNotFound,
|
|
1782
|
+
WrongObjectType,
|
|
1783
|
+
NoMergeBase,
|
|
1784
|
+
PullNotFound,
|
|
1785
|
+
PullExists,
|
|
1786
|
+
PullStateConflict,
|
|
1787
|
+
BranchMissing,
|
|
1788
|
+
NothingToMerge,
|
|
1789
|
+
MergeConflict,
|
|
1790
|
+
ValidationError,
|
|
1791
|
+
StoreError,
|
|
1792
|
+
PackIngestError,
|
|
1793
|
+
WireProtocolError,
|
|
1794
|
+
],
|
|
1795
|
+
}) {
|
|
1796
|
+
}
|
|
1797
|
+
/**
|
|
1798
|
+
* `Git.RepoStore` — the repository block as a service: every route reaches
|
|
1799
|
+
* a repository through it. `ReposDurableObject` provides it over the
|
|
1800
|
+
* {@link GitRepo} Durable Object namespace. It is the seam for decorating
|
|
1801
|
+
* repositories (hook `commitPush`, `updateRef`, `mergePull` to observe ref
|
|
1802
|
+
* moves) or for implementing {@link GitRepoShape} over another store.
|
|
1803
|
+
*
|
|
1804
|
+
* @binding
|
|
1805
|
+
*/
|
|
1806
|
+
export class RepoStore extends Context.Service()("alchemy/Git/RepoStore") {
|
|
1807
|
+
}
|
|
1808
|
+
/**
|
|
1809
|
+
* The Repo DO implementation Layer. Requires the {@link BlobStore}
|
|
1810
|
+
* service (provide `Git.BlobStoreR2(yourBucket)` — or any other
|
|
1811
|
+
* implementation — in the same layer graph) and the {@link Registry}
|
|
1812
|
+
* namespace.
|
|
1813
|
+
*/
|
|
1814
|
+
export const GitRepoLive = GitRepo.make(Effect.gen(function* () {
|
|
1815
|
+
// ── Outer init: resolve bindings + namespaces (runs at plan time too) ──
|
|
1816
|
+
const state = yield* Cloudflare.DurableObjectState;
|
|
1817
|
+
// The building-blocks seam: bulk bytes live behind whatever BlobStore
|
|
1818
|
+
// the user's layer graph provides (R2 by default, S3, ...).
|
|
1819
|
+
const blobs = yield* BlobStore;
|
|
1820
|
+
// The push pipeline's hasher (DESIGN §22.7): a self-binding fan-out in
|
|
1821
|
+
// production, in-process in tests without the binding.
|
|
1822
|
+
const hasher = yield* Hasher;
|
|
1823
|
+
const registry = yield* RegistryStore;
|
|
1824
|
+
const selfNamespace = yield* Cloudflare.DurableObjectScope;
|
|
1825
|
+
return Effect.gen(function* () {
|
|
1826
|
+
// ── Inner init: per-instance construction (runtime only) ────────────
|
|
1827
|
+
const sql = makeSqlClient(state);
|
|
1828
|
+
yield* initRepoSchema(sql).pipe(Effect.orDie);
|
|
1829
|
+
// Isolate-wide, not per repo: the memory it meters is shared.
|
|
1830
|
+
const pushSemaphore = yield* isolatePushGate;
|
|
1831
|
+
// ── config helpers ───────────────────────────────────────────────────
|
|
1832
|
+
const getConfig = (key) => sql
|
|
1833
|
+
.first(`SELECT value FROM config WHERE key = ?`, key)
|
|
1834
|
+
.pipe(Effect.map((row) => row?.value));
|
|
1835
|
+
const setConfig = (key, value) => sql.run(`INSERT INTO config (key, value) VALUES (?, ?)
|
|
1836
|
+
ON CONFLICT (key) DO UPDATE SET value = excluded.value`, key, value);
|
|
1837
|
+
/**
|
|
1838
|
+
* Repo metadata from the `config` table. The `objects` breakdown is
|
|
1839
|
+
* a GROUP BY over the whole `objects` table — on a large repo that
|
|
1840
|
+
* scan walks pages dense with inline zdata and was measured at
|
|
1841
|
+
* ~1.5 s per call (DESIGN §22). It is therefore opt-in: only the
|
|
1842
|
+
* REST repo-detail responses pay for it; the wire path, auth, and
|
|
1843
|
+
* every other caller get zeros there and never touch the table.
|
|
1844
|
+
*/
|
|
1845
|
+
const readMetaWith = (withStats) => Effect.gen(function* () {
|
|
1846
|
+
const rows = yield* sql.all(`SELECT key, value FROM config`);
|
|
1847
|
+
const map = new Map(rows.map((row) => [row.key, row.value]));
|
|
1848
|
+
const repoId = map.get("repo_id");
|
|
1849
|
+
if (repoId === undefined)
|
|
1850
|
+
return undefined;
|
|
1851
|
+
const stats = withStats
|
|
1852
|
+
? yield* sql.all(
|
|
1853
|
+
// Row-resident blobs are "loose" (awaiting compaction);
|
|
1854
|
+
// row-resident commits/trees/tags are "resident" — they stay
|
|
1855
|
+
// in SQLite for the life of the repo (Compact.ts BLOB_TYPE).
|
|
1856
|
+
`SELECT CASE WHEN location = 'row' AND type <> 3 THEN 'resident'
|
|
1857
|
+
WHEN location = 'row' THEN 'loose'
|
|
1858
|
+
ELSE location END AS bucket,
|
|
1859
|
+
COUNT(*) AS n, COALESCE(SUM(zsize), 0) AS bytes
|
|
1860
|
+
FROM objects WHERE ${LIVE_OBJECTS} GROUP BY bucket`)
|
|
1861
|
+
: [];
|
|
1862
|
+
const byLocation = new Map(stats.map((row) => [row.bucket, row]));
|
|
1863
|
+
return {
|
|
1864
|
+
repoId,
|
|
1865
|
+
owner: map.get("owner") ?? "",
|
|
1866
|
+
name: map.get("name") ?? "",
|
|
1867
|
+
defaultBranch: map.get("default_branch") ?? "main",
|
|
1868
|
+
description: map.get("description") ?? null,
|
|
1869
|
+
readOnly: map.get("read_only") === "1",
|
|
1870
|
+
public: map.get("public") === "1",
|
|
1871
|
+
forkOf: map.get("fork_of") ?? null,
|
|
1872
|
+
status: (map.get("status") ?? "ready"),
|
|
1873
|
+
createdAt: Number(map.get("created_at") ?? 0),
|
|
1874
|
+
lastPush: map.get("last_push") === undefined
|
|
1875
|
+
? null
|
|
1876
|
+
: JSON.parse(map.get("last_push")),
|
|
1877
|
+
objects: {
|
|
1878
|
+
loose: byLocation.get("loose")?.n ?? 0,
|
|
1879
|
+
resident: byLocation.get("resident")?.n ?? 0,
|
|
1880
|
+
packed: byLocation.get("pack")?.n ?? 0,
|
|
1881
|
+
r2: byLocation.get("r2")?.n ?? 0,
|
|
1882
|
+
bytes: stats.reduce((sum, row) => sum + row.bytes, 0),
|
|
1883
|
+
},
|
|
1884
|
+
};
|
|
1885
|
+
});
|
|
1886
|
+
const readMeta = readMetaWith(false);
|
|
1887
|
+
const readMetaStats = readMetaWith(true);
|
|
1888
|
+
const requireFrom = (read) => read.pipe(Effect.flatMap((meta) => meta === undefined
|
|
1889
|
+
? Effect.fail(new RepoNotFound({ owner: "", repo: "" }))
|
|
1890
|
+
: Effect.succeed(meta)));
|
|
1891
|
+
/** Cheap: config only. `objects` reads as zeros. */
|
|
1892
|
+
const requireMeta = requireFrom(readMeta);
|
|
1893
|
+
/** The REST detail shape, with the full objects aggregate. */
|
|
1894
|
+
const requireMetaStats = requireFrom(readMetaStats);
|
|
1895
|
+
/** The object store, keyed by the current repoId. */
|
|
1896
|
+
const storeFor = (repoId) => makeObjectStore({ sql, blobs, repoId });
|
|
1897
|
+
// ── refs ─────────────────────────────────────────────────────────────
|
|
1898
|
+
/** Peels a (possibly annotated-tag) oid to its final non-tag target. */
|
|
1899
|
+
const peelOid = (repoId, oid) => Effect.gen(function* () {
|
|
1900
|
+
const objects = storeFor(repoId);
|
|
1901
|
+
let current = oid;
|
|
1902
|
+
for (let hops = 0; hops < 16; hops++) {
|
|
1903
|
+
const meta = yield* objects.getMeta(current);
|
|
1904
|
+
if (meta === undefined)
|
|
1905
|
+
return undefined;
|
|
1906
|
+
if (meta.type !== ObjectType.tag) {
|
|
1907
|
+
return hops === 0 ? undefined : current;
|
|
1908
|
+
}
|
|
1909
|
+
const content = yield* objects.readContent(current);
|
|
1910
|
+
const parsed = yield* parseTag(content).pipe(Effect.mapError((error) => new StoreError({ reason: error.reason })));
|
|
1911
|
+
current = parsed.object;
|
|
1912
|
+
}
|
|
1913
|
+
return current;
|
|
1914
|
+
});
|
|
1915
|
+
/**
|
|
1916
|
+
* Resolves a refname (short or full) or 40-hex oid to an object oid.
|
|
1917
|
+
* Candidates for short names: `refs/heads/<name>`, `refs/tags/<name>`.
|
|
1918
|
+
* `undefined` means HEAD (the default branch).
|
|
1919
|
+
*/
|
|
1920
|
+
const resolveRevision = Effect.fn(function* (defaultBranch, rev) {
|
|
1921
|
+
const refName = rev === undefined ? `refs/heads/${defaultBranch}` : rev;
|
|
1922
|
+
if (isOid(refName))
|
|
1923
|
+
return refName;
|
|
1924
|
+
const candidates = refName.startsWith("refs/")
|
|
1925
|
+
? [refName]
|
|
1926
|
+
: [`refs/heads/${refName}`, `refs/tags/${refName}`];
|
|
1927
|
+
for (const candidate of candidates) {
|
|
1928
|
+
const row = yield* sql.first(`SELECT name, oid FROM refs WHERE name = ?`, candidate);
|
|
1929
|
+
if (row !== undefined)
|
|
1930
|
+
return row.oid;
|
|
1931
|
+
}
|
|
1932
|
+
return yield* new RefNotFound({ ref: refName });
|
|
1933
|
+
});
|
|
1934
|
+
/** Resolves a revision all the way to a COMMIT oid (peels tags). */
|
|
1935
|
+
const resolveToCommit = Effect.fn(function* (repoId, defaultBranch, rev) {
|
|
1936
|
+
const oid = yield* resolveRevision(defaultBranch, rev);
|
|
1937
|
+
const objects = storeFor(repoId);
|
|
1938
|
+
const meta = yield* objects.getMeta(oid);
|
|
1939
|
+
if (meta === undefined)
|
|
1940
|
+
return yield* new ObjectNotFound({ oid });
|
|
1941
|
+
if (meta.type === ObjectType.commit)
|
|
1942
|
+
return oid;
|
|
1943
|
+
if (meta.type === ObjectType.tag) {
|
|
1944
|
+
const peeled = yield* peelOid(repoId, oid);
|
|
1945
|
+
if (peeled === undefined) {
|
|
1946
|
+
return yield* new ObjectNotFound({ oid });
|
|
1947
|
+
}
|
|
1948
|
+
const peeledMeta = yield* objects.getMeta(peeled);
|
|
1949
|
+
if (peeledMeta === undefined) {
|
|
1950
|
+
return yield* new ObjectNotFound({ oid: peeled });
|
|
1951
|
+
}
|
|
1952
|
+
if (peeledMeta.type !== ObjectType.commit) {
|
|
1953
|
+
return yield* new WrongObjectType({
|
|
1954
|
+
oid: peeled,
|
|
1955
|
+
expected: "commit",
|
|
1956
|
+
actual: objectTypeName(peeledMeta.type),
|
|
1957
|
+
});
|
|
1958
|
+
}
|
|
1959
|
+
return peeled;
|
|
1960
|
+
}
|
|
1961
|
+
return yield* new WrongObjectType({
|
|
1962
|
+
oid,
|
|
1963
|
+
expected: "commit",
|
|
1964
|
+
actual: objectTypeName(meta.type),
|
|
1965
|
+
});
|
|
1966
|
+
});
|
|
1967
|
+
const listAllRefs = (repoId, prefix) => Effect.gen(function* () {
|
|
1968
|
+
const rows = prefix === undefined || prefix.length === 0
|
|
1969
|
+
? yield* sql.all(`SELECT name, oid FROM refs ORDER BY name`)
|
|
1970
|
+
: yield* sql.all(`SELECT name, oid FROM refs WHERE name >= ? AND name < ? ORDER BY name`, prefix,
|
|
1971
|
+
// next lexicographic sibling of the prefix
|
|
1972
|
+
`${prefix.slice(0, -1)}${String.fromCharCode(prefix.charCodeAt(prefix.length - 1) + 1)}`);
|
|
1973
|
+
const out = [];
|
|
1974
|
+
for (const row of rows) {
|
|
1975
|
+
const peeled = row.name.startsWith("refs/tags/")
|
|
1976
|
+
? yield* peelOid(repoId, row.oid)
|
|
1977
|
+
: undefined;
|
|
1978
|
+
out.push(peeled === undefined
|
|
1979
|
+
? { name: row.name, oid: row.oid }
|
|
1980
|
+
: { name: row.name, oid: row.oid, peeled });
|
|
1981
|
+
}
|
|
1982
|
+
return out;
|
|
1983
|
+
});
|
|
1984
|
+
const finalizeRefTxn = (options) => sql
|
|
1985
|
+
.transactionSync((raw) => {
|
|
1986
|
+
if (options.pushId !== undefined) {
|
|
1987
|
+
const push = raw
|
|
1988
|
+
.exec(`SELECT state FROM pushes WHERE push_id = ?`, options.pushId)
|
|
1989
|
+
.toArray()[0];
|
|
1990
|
+
if (push?.state !== "staging")
|
|
1991
|
+
return options.commands.map((command) => ({
|
|
1992
|
+
ref: command.ref,
|
|
1993
|
+
ok: false,
|
|
1994
|
+
reason: "push is no longer active",
|
|
1995
|
+
}));
|
|
1996
|
+
}
|
|
1997
|
+
const currentOf = (name) => {
|
|
1998
|
+
const rows = raw
|
|
1999
|
+
.exec(`SELECT name, oid FROM refs WHERE name = ?`, name)
|
|
2000
|
+
.toArray();
|
|
2001
|
+
return rows.length > 0 ? rows[0].oid : ZERO_OID;
|
|
2002
|
+
};
|
|
2003
|
+
const results = [];
|
|
2004
|
+
// atomic: verify every CAS before writing anything
|
|
2005
|
+
if (options.atomic && options.unconditional !== true) {
|
|
2006
|
+
const failed = options.commands.some((cmd) => currentOf(cmd.ref) !== cmd.oldOid);
|
|
2007
|
+
if (failed) {
|
|
2008
|
+
for (const cmd of options.commands) {
|
|
2009
|
+
results.push({
|
|
2010
|
+
ref: cmd.ref,
|
|
2011
|
+
ok: false,
|
|
2012
|
+
reason: currentOf(cmd.ref) === cmd.oldOid
|
|
2013
|
+
? "atomic transaction failed"
|
|
2014
|
+
: "fetch first",
|
|
2015
|
+
});
|
|
2016
|
+
}
|
|
2017
|
+
return results;
|
|
2018
|
+
}
|
|
2019
|
+
}
|
|
2020
|
+
let anyOk = false;
|
|
2021
|
+
for (const cmd of options.commands) {
|
|
2022
|
+
if (options.unconditional !== true &&
|
|
2023
|
+
currentOf(cmd.ref) !== cmd.oldOid) {
|
|
2024
|
+
results.push({
|
|
2025
|
+
ref: cmd.ref,
|
|
2026
|
+
ok: false,
|
|
2027
|
+
reason: "fetch first",
|
|
2028
|
+
});
|
|
2029
|
+
continue;
|
|
2030
|
+
}
|
|
2031
|
+
if (cmd.newOid === ZERO_OID) {
|
|
2032
|
+
raw.exec(`DELETE FROM refs WHERE name = ?`, cmd.ref);
|
|
2033
|
+
}
|
|
2034
|
+
else {
|
|
2035
|
+
raw.exec(`INSERT INTO refs (name, oid) VALUES (?, ?)
|
|
2036
|
+
ON CONFLICT (name) DO UPDATE SET oid = excluded.oid`, cmd.ref, cmd.newOid);
|
|
2037
|
+
}
|
|
2038
|
+
results.push({ ref: cmd.ref, ok: true });
|
|
2039
|
+
anyOk = true;
|
|
2040
|
+
}
|
|
2041
|
+
if (anyOk || options.commands.length === 0) {
|
|
2042
|
+
if (options.pushId !== undefined) {
|
|
2043
|
+
// Committing the push row is what makes its objects live
|
|
2044
|
+
// (LIVE_OBJECTS, DESIGN §22.14); nulling `staged_push` on
|
|
2045
|
+
// every row is a rewrite of the whole staged set and runs
|
|
2046
|
+
// after the response (`flipPush`), or inside this
|
|
2047
|
+
// transaction for callers that want it settled now.
|
|
2048
|
+
if (options.deferFlip !== true) {
|
|
2049
|
+
raw.exec(`UPDATE objects SET staged_push = NULL WHERE staged_push = ?`, options.pushId);
|
|
2050
|
+
}
|
|
2051
|
+
raw.exec(`UPDATE pushes SET state = 'committed' WHERE push_id = ?`, options.pushId);
|
|
2052
|
+
}
|
|
2053
|
+
// Multi-row inserts under SQLite's 100-parameter cap: a
|
|
2054
|
+
// per-row exec was most of finalize once rows were
|
|
2055
|
+
// coordinates (DESIGN §22.14).
|
|
2056
|
+
for (let at = 0; at < options.graph.length; at += 25) {
|
|
2057
|
+
const part = options.graph.slice(at, at + 25);
|
|
2058
|
+
raw.exec(`INSERT OR IGNORE INTO commits (oid, tree, gen, commit_time) VALUES ${part.map(() => "(?, ?, ?, ?)").join(", ")}`, ...part.flatMap((commit) => [
|
|
2059
|
+
commit.oid,
|
|
2060
|
+
commit.tree,
|
|
2061
|
+
commit.gen,
|
|
2062
|
+
commit.commitTime,
|
|
2063
|
+
]));
|
|
2064
|
+
}
|
|
2065
|
+
const parentRows = options.graph.flatMap((commit) => commit.parents.map((parent, ord) => [commit.oid, parent, ord]));
|
|
2066
|
+
for (let at = 0; at < parentRows.length; at += 33) {
|
|
2067
|
+
const part = parentRows.slice(at, at + 33);
|
|
2068
|
+
raw.exec(`INSERT OR IGNORE INTO commit_parents (oid, parent, ord) VALUES ${part.map(() => "(?, ?, ?)").join(", ")}`, ...part.flat());
|
|
2069
|
+
}
|
|
2070
|
+
if (options.onCommitted !== undefined) {
|
|
2071
|
+
options.onCommitted(raw);
|
|
2072
|
+
}
|
|
2073
|
+
// First-branch-push default branch fixup: if the configured
|
|
2074
|
+
// default branch does not exist but a branch was just created,
|
|
2075
|
+
// repoint the default at it (prefer main/master).
|
|
2076
|
+
const configured = raw
|
|
2077
|
+
.exec(`SELECT value FROM config WHERE key = 'default_branch'`)
|
|
2078
|
+
.toArray()[0]?.value;
|
|
2079
|
+
if (configured !== undefined) {
|
|
2080
|
+
const exists = raw
|
|
2081
|
+
.exec(`SELECT name, oid FROM refs WHERE name = ?`, `refs/heads/${configured}`)
|
|
2082
|
+
.toArray();
|
|
2083
|
+
if (exists.length === 0) {
|
|
2084
|
+
const branches = raw
|
|
2085
|
+
.exec(`SELECT name, oid FROM refs WHERE name LIKE 'refs/heads/%' ORDER BY name`)
|
|
2086
|
+
.toArray()
|
|
2087
|
+
.map((row) => row.name.slice("refs/heads/".length));
|
|
2088
|
+
const pick = branches.find((b) => b === "main") ??
|
|
2089
|
+
branches.find((b) => b === "master") ??
|
|
2090
|
+
branches[0];
|
|
2091
|
+
if (pick !== undefined) {
|
|
2092
|
+
raw.exec(`UPDATE config SET value = ? WHERE key = 'default_branch'`, pick);
|
|
2093
|
+
}
|
|
2094
|
+
}
|
|
2095
|
+
}
|
|
2096
|
+
}
|
|
2097
|
+
return results;
|
|
2098
|
+
})
|
|
2099
|
+
.pipe(
|
|
2100
|
+
// Any committed ref movement changes what an anonymous reader
|
|
2101
|
+
// can see — republish the head snapshot (DESIGN.md §21).
|
|
2102
|
+
Effect.tap((results) => results.some((result) => result.ok)
|
|
2103
|
+
? writeHeadSnapshot
|
|
2104
|
+
: Effect.void));
|
|
2105
|
+
/** Computes gen/commit_time rows for staged commits (§3.6 step 6). */
|
|
2106
|
+
const computeGraphRows = (staged) => Effect.gen(function* () {
|
|
2107
|
+
const stagedByOid = new Map(staged.map((c) => [c.oid, c]));
|
|
2108
|
+
const externalParents = Array.from(new Set(staged.flatMap((c) => c.parents.filter((p) => !stagedByOid.has(p)))));
|
|
2109
|
+
const liveGens = new Map();
|
|
2110
|
+
if (externalParents.length > 0) {
|
|
2111
|
+
const rows = yield* sql.inChunks((ph) => `SELECT oid, gen FROM commits WHERE oid IN (${ph})`, externalParents);
|
|
2112
|
+
for (const row of rows)
|
|
2113
|
+
liveGens.set(row.oid, row.gen);
|
|
2114
|
+
}
|
|
2115
|
+
const gens = new Map();
|
|
2116
|
+
const genOf = (oid, depth) => {
|
|
2117
|
+
const known = gens.get(oid);
|
|
2118
|
+
if (known !== undefined)
|
|
2119
|
+
return known;
|
|
2120
|
+
const live = liveGens.get(oid);
|
|
2121
|
+
if (live !== undefined)
|
|
2122
|
+
return live;
|
|
2123
|
+
const commit = stagedByOid.get(oid);
|
|
2124
|
+
// Missing parent (shallow boundary) counts as gen 0.
|
|
2125
|
+
if (commit === undefined || depth > 100_000)
|
|
2126
|
+
return 0;
|
|
2127
|
+
const gen = commit.parents.length === 0
|
|
2128
|
+
? 1
|
|
2129
|
+
: Math.max(...commit.parents.map((p) => genOf(p, depth + 1))) +
|
|
2130
|
+
1;
|
|
2131
|
+
gens.set(oid, gen);
|
|
2132
|
+
return gen;
|
|
2133
|
+
};
|
|
2134
|
+
return staged.map((commit) => ({
|
|
2135
|
+
oid: commit.oid,
|
|
2136
|
+
tree: commit.tree,
|
|
2137
|
+
gen: genOf(commit.oid, 0),
|
|
2138
|
+
commitTime: commit.commitTime,
|
|
2139
|
+
parents: commit.parents,
|
|
2140
|
+
}));
|
|
2141
|
+
});
|
|
2142
|
+
// ── pull requests ────────────────────────────────────────────────────
|
|
2143
|
+
/** `main` or `refs/heads/main` → `refs/heads/main`; branches only. */
|
|
2144
|
+
const normalizeBranchRef = Effect.fn(function* (name) {
|
|
2145
|
+
const full = name.startsWith("refs/") ? name : `refs/heads/${name}`;
|
|
2146
|
+
if (!full.startsWith("refs/heads/") ||
|
|
2147
|
+
full.length <= "refs/heads/".length ||
|
|
2148
|
+
!REF_NAME_REGEX.test(full)) {
|
|
2149
|
+
return yield* new ValidationError({
|
|
2150
|
+
message: `not a branch name: ${name} (only refs/heads/* is legal)`,
|
|
2151
|
+
});
|
|
2152
|
+
}
|
|
2153
|
+
return full;
|
|
2154
|
+
});
|
|
2155
|
+
const pullStateOf = (state) => state === "closed" ? "closed" : state === "merged" ? "merged" : "open";
|
|
2156
|
+
const rowToPull = (row) => ({
|
|
2157
|
+
number: row.number,
|
|
2158
|
+
title: row.title,
|
|
2159
|
+
body: row.body,
|
|
2160
|
+
baseRef: row.base_ref,
|
|
2161
|
+
headRef: row.head_ref,
|
|
2162
|
+
state: pullStateOf(row.state),
|
|
2163
|
+
createdAt: row.created_at,
|
|
2164
|
+
updatedAt: row.updated_at,
|
|
2165
|
+
mergedAt: row.merged_at,
|
|
2166
|
+
mergeCommit: row.merge_commit,
|
|
2167
|
+
});
|
|
2168
|
+
const loadPull = Effect.fn(function* (number) {
|
|
2169
|
+
const row = yield* sql.first(`SELECT * FROM pulls WHERE number = ?`, number);
|
|
2170
|
+
if (row === undefined) {
|
|
2171
|
+
return yield* new PullNotFound({ number });
|
|
2172
|
+
}
|
|
2173
|
+
return row;
|
|
2174
|
+
});
|
|
2175
|
+
/**
|
|
2176
|
+
* The same gen-ordered merge-base paint walk `compareCommits` runs,
|
|
2177
|
+
* reduced to what the PR surface needs: the best common ancestor plus
|
|
2178
|
+
* ahead/behind counts. `mergeBase === head` ⇔ head is reachable from
|
|
2179
|
+
* base (up-to-date); `mergeBase === base` ⇔ base is reachable from
|
|
2180
|
+
* head (fast-forwardable) — the gen ordering guarantees a node's
|
|
2181
|
+
* flags are complete when it pops. A tip missing from the commit
|
|
2182
|
+
* graph reports `saturated` (uncomputable), never an error.
|
|
2183
|
+
*/
|
|
2184
|
+
const paintWalk = Effect.fn(function* (baseOid, headOid, maxPops) {
|
|
2185
|
+
const BASE = 1;
|
|
2186
|
+
const HEAD = 2;
|
|
2187
|
+
const BOTH = 3;
|
|
2188
|
+
const flags = new Map();
|
|
2189
|
+
flags.set(baseOid, BASE);
|
|
2190
|
+
flags.set(headOid, (flags.get(headOid) ?? 0) | HEAD);
|
|
2191
|
+
const heap = [];
|
|
2192
|
+
const rowOf = (oid) => sql.first(`SELECT gen, commit_time FROM commits WHERE oid = ?`, oid);
|
|
2193
|
+
for (const oid of new Set([baseOid, headOid])) {
|
|
2194
|
+
const row = yield* rowOf(oid);
|
|
2195
|
+
if (row === undefined) {
|
|
2196
|
+
return {
|
|
2197
|
+
mergeBase: undefined,
|
|
2198
|
+
aheadBy: 0,
|
|
2199
|
+
behindBy: 0,
|
|
2200
|
+
saturated: true,
|
|
2201
|
+
};
|
|
2202
|
+
}
|
|
2203
|
+
heapPush(heap, { oid, gen: row.gen, time: row.commit_time });
|
|
2204
|
+
}
|
|
2205
|
+
let mergeBase;
|
|
2206
|
+
let aheadBy = 0;
|
|
2207
|
+
let behindBy = 0;
|
|
2208
|
+
let pops = 0;
|
|
2209
|
+
while (heap.length > 0 && pops < maxPops) {
|
|
2210
|
+
// stop once nothing in the heap can still change the counts
|
|
2211
|
+
if (mergeBase !== undefined &&
|
|
2212
|
+
heap.every((n) => (flags.get(n.oid) & BOTH) === BOTH)) {
|
|
2213
|
+
break;
|
|
2214
|
+
}
|
|
2215
|
+
const node = heapPop(heap);
|
|
2216
|
+
pops++;
|
|
2217
|
+
const f = flags.get(node.oid);
|
|
2218
|
+
if ((f & BOTH) === BOTH) {
|
|
2219
|
+
if (mergeBase === undefined)
|
|
2220
|
+
mergeBase = node.oid;
|
|
2221
|
+
}
|
|
2222
|
+
else if (f === HEAD) {
|
|
2223
|
+
aheadBy++;
|
|
2224
|
+
}
|
|
2225
|
+
else {
|
|
2226
|
+
behindBy++;
|
|
2227
|
+
}
|
|
2228
|
+
const parents = yield* sql.all(`SELECT parent FROM commit_parents WHERE oid = ? ORDER BY ord`, node.oid);
|
|
2229
|
+
for (const { parent } of parents) {
|
|
2230
|
+
const prev = flags.get(parent) ?? 0;
|
|
2231
|
+
const next = prev | f;
|
|
2232
|
+
if (next === prev)
|
|
2233
|
+
continue;
|
|
2234
|
+
flags.set(parent, next);
|
|
2235
|
+
if (prev === 0) {
|
|
2236
|
+
const row = yield* rowOf(parent);
|
|
2237
|
+
if (row === undefined)
|
|
2238
|
+
continue; // shallow boundary
|
|
2239
|
+
heapPush(heap, {
|
|
2240
|
+
oid: parent,
|
|
2241
|
+
gen: row.gen,
|
|
2242
|
+
time: row.commit_time,
|
|
2243
|
+
});
|
|
2244
|
+
}
|
|
2245
|
+
}
|
|
2246
|
+
}
|
|
2247
|
+
return {
|
|
2248
|
+
mergeBase,
|
|
2249
|
+
aheadBy,
|
|
2250
|
+
behindBy,
|
|
2251
|
+
saturated: pops >= maxPops && heap.length > 0,
|
|
2252
|
+
};
|
|
2253
|
+
});
|
|
2254
|
+
/** The root tree of a commit, via the commit-graph table. */
|
|
2255
|
+
const treeOfCommit = Effect.fn(function* (oid) {
|
|
2256
|
+
const row = yield* sql.first(`SELECT tree FROM commits WHERE oid = ?`, oid);
|
|
2257
|
+
if (row === undefined) {
|
|
2258
|
+
return yield* new StoreError({
|
|
2259
|
+
reason: `commit ${oid} missing from the commit graph`,
|
|
2260
|
+
});
|
|
2261
|
+
}
|
|
2262
|
+
return row.tree;
|
|
2263
|
+
});
|
|
2264
|
+
// ── alarm scheduling ─────────────────────────────────────────────────
|
|
2265
|
+
const armAlarmAt = (time) => Effect.gen(function* () {
|
|
2266
|
+
const existing = yield* state.storage.getAlarm();
|
|
2267
|
+
if (existing === null || existing > time) {
|
|
2268
|
+
yield* state.storage.setAlarm(time);
|
|
2269
|
+
}
|
|
2270
|
+
});
|
|
2271
|
+
const upsertJob = (kind, detail) => sql.run(`INSERT INTO jobs (kind, state, detail, updated_at) VALUES (?, 'running', ?, ?)
|
|
2272
|
+
ON CONFLICT (kind) DO UPDATE SET state = 'running', detail = excluded.detail, updated_at = excluded.updated_at`, kind, detail, Date.now());
|
|
2273
|
+
// ── bootstrap (create / fork / import) ───────────────────────────────
|
|
2274
|
+
const seedConfig = Effect.fn(function* (input, status) {
|
|
2275
|
+
const createdAt = Date.now();
|
|
2276
|
+
yield* setConfig("repo_id", input.repoId);
|
|
2277
|
+
yield* setConfig("owner", input.owner.toLowerCase());
|
|
2278
|
+
yield* setConfig("name", input.name.toLowerCase());
|
|
2279
|
+
yield* setConfig("default_branch", input.defaultBranch);
|
|
2280
|
+
if (input.description !== null) {
|
|
2281
|
+
yield* setConfig("description", input.description);
|
|
2282
|
+
}
|
|
2283
|
+
yield* setConfig("read_only", input.readOnly ? "1" : "0");
|
|
2284
|
+
yield* setConfig("public", input.public ? "1" : "0");
|
|
2285
|
+
if (input.forkOf !== null) {
|
|
2286
|
+
yield* setConfig("fork_of", input.forkOf);
|
|
2287
|
+
}
|
|
2288
|
+
yield* setConfig("status", status);
|
|
2289
|
+
yield* readMeta.pipe(Effect.flatMap((meta) => meta === undefined ? Effect.void : syncSummary(meta)), Effect.ignore);
|
|
2290
|
+
const existing = yield* getConfig("created_at");
|
|
2291
|
+
if (existing === undefined) {
|
|
2292
|
+
yield* setConfig("created_at", String(createdAt));
|
|
2293
|
+
}
|
|
2294
|
+
const meta = yield* readMeta;
|
|
2295
|
+
return meta;
|
|
2296
|
+
});
|
|
2297
|
+
const bootstrap = Effect.fn(function* (input, status) {
|
|
2298
|
+
const meta = yield* seedConfig(input, status);
|
|
2299
|
+
return { meta };
|
|
2300
|
+
});
|
|
2301
|
+
// ── wire protocol drivers ────────────────────────────────────────────
|
|
2302
|
+
/** Parses `/:owner/:repo[.git]/<endpoint>` out of the request URL. */
|
|
2303
|
+
const parseWirePath = (url) => {
|
|
2304
|
+
const parsed = new URL(url, "http://repo");
|
|
2305
|
+
const segments = parsed.pathname.split("/").filter(Boolean);
|
|
2306
|
+
if (segments.length < 3)
|
|
2307
|
+
return undefined;
|
|
2308
|
+
const owner = decodeURIComponent(segments[0]).toLowerCase();
|
|
2309
|
+
let repo = decodeURIComponent(segments[1]).toLowerCase();
|
|
2310
|
+
if (repo.endsWith(".git"))
|
|
2311
|
+
repo = repo.slice(0, -4);
|
|
2312
|
+
const endpoint = segments.slice(2).join("/");
|
|
2313
|
+
return {
|
|
2314
|
+
owner,
|
|
2315
|
+
repo,
|
|
2316
|
+
endpoint,
|
|
2317
|
+
service: parsed.searchParams.get("service") ?? undefined,
|
|
2318
|
+
};
|
|
2319
|
+
};
|
|
2320
|
+
const wire503 = HttpServerResponse.empty({
|
|
2321
|
+
status: 503,
|
|
2322
|
+
headers: { "retry-after": "10" },
|
|
2323
|
+
});
|
|
2324
|
+
/** GET info/refs — the v0 advertisement. */
|
|
2325
|
+
const handleInfoRefs = (request, service, meta) => Effect.gen(function* () {
|
|
2326
|
+
if (service !== "git-upload-pack" && service !== "git-receive-pack") {
|
|
2327
|
+
return HttpServerResponse.text("smart HTTP only (dumb protocol not supported)", { status: 400 });
|
|
2328
|
+
}
|
|
2329
|
+
const refs = yield* listAllRefs(meta.repoId);
|
|
2330
|
+
const body = buildAdvertisement({
|
|
2331
|
+
service,
|
|
2332
|
+
defaultBranch: meta.defaultBranch,
|
|
2333
|
+
refs,
|
|
2334
|
+
});
|
|
2335
|
+
return HttpServerResponse.uint8Array(body, {
|
|
2336
|
+
contentType: `application/x-${service}-advertisement`,
|
|
2337
|
+
headers: noCache,
|
|
2338
|
+
});
|
|
2339
|
+
});
|
|
2340
|
+
/** POST git-upload-pack — negotiation + pack (DESIGN.md §2.3). */
|
|
2341
|
+
const handleUploadPack = (request, meta) => Effect.gen(function* () {
|
|
2342
|
+
const rawBody = new Uint8Array(yield* request.arrayBuffer);
|
|
2343
|
+
const body = yield* gunzipIfNeeded(rawBody, request.headers["content-encoding"]);
|
|
2344
|
+
const resultType = "application/x-git-upload-pack-result";
|
|
2345
|
+
const errResponse = (message) => HttpServerResponse.uint8Array(errPkt(message), {
|
|
2346
|
+
contentType: resultType,
|
|
2347
|
+
headers: noCache,
|
|
2348
|
+
});
|
|
2349
|
+
const parsed = yield* decodePktLines(body).pipe(Effect.flatMap(parseUploadPackRequest), Effect.map(Option.some), Effect.catchTag("PktLineError", (e) => Effect.succeed(Option.none()).pipe(Effect.tap(() => Effect.logWarning(`upload-pack: ${e.reason}`)))), Effect.catchTag("WireProtocolError", (e) => Effect.succeed(Option.none()).pipe(Effect.tap(() => Effect.logWarning(`upload-pack: ${e.reason}`)))));
|
|
2350
|
+
if (Option.isNone(parsed)) {
|
|
2351
|
+
return errResponse("malformed upload-pack request");
|
|
2352
|
+
}
|
|
2353
|
+
const req = parsed.value;
|
|
2354
|
+
const objects = storeFor(meta.repoId);
|
|
2355
|
+
const sideband = req.capabilities.has("side-band-64k");
|
|
2356
|
+
const noDone = req.capabilities.has("no-done");
|
|
2357
|
+
const commons = yield* objects.filterExisting(req.haves);
|
|
2358
|
+
// Negotiation round without done and nothing in common: answer
|
|
2359
|
+
// NAK and wait for the next round (or done). EXCEPT when the
|
|
2360
|
+
// request carries `deepen` — the shallow/unshallow section must
|
|
2361
|
+
// precede the NAK ("fatal: expected shallow/unshallow, got NAK"
|
|
2362
|
+
// otherwise), so depth-carrying rounds fall through to the
|
|
2363
|
+
// closure computation below.
|
|
2364
|
+
if (!req.done && commons.length === 0 && req.depth === undefined) {
|
|
2365
|
+
return HttpServerResponse.uint8Array(pktText("NAK"), {
|
|
2366
|
+
contentType: resultType,
|
|
2367
|
+
headers: noCache,
|
|
2368
|
+
});
|
|
2369
|
+
}
|
|
2370
|
+
// Bundle fast path (DESIGN.md §12.2): a full clone whose wants are
|
|
2371
|
+
// all covered by the current bundle is served as bytes straight
|
|
2372
|
+
// from R2 — no closure walk, no per-object reads. `bundleCovers`
|
|
2373
|
+
// refuses anything with haves/depth/shallow state.
|
|
2374
|
+
const bundle = yield* readBundle;
|
|
2375
|
+
if (req.done &&
|
|
2376
|
+
bundle !== undefined &&
|
|
2377
|
+
bundleCovers(bundle, {
|
|
2378
|
+
wants: req.wants,
|
|
2379
|
+
haves: req.haves,
|
|
2380
|
+
depth: req.depth,
|
|
2381
|
+
clientShallow: req.clientShallow,
|
|
2382
|
+
})) {
|
|
2383
|
+
// The DO does NOT stream the pack: it hands the Worker a
|
|
2384
|
+
// *marker* naming the R2 object, and the Worker streams those
|
|
2385
|
+
// bytes to the client itself (DESIGN.md §11, serving plane).
|
|
2386
|
+
// Auth and planning still happen here — where tokens and refs
|
|
2387
|
+
// live — but no pack byte transits this object, which is the
|
|
2388
|
+
// whole point of splitting the planes.
|
|
2389
|
+
const found = yield* blobs
|
|
2390
|
+
.head(bundle.key)
|
|
2391
|
+
.pipe(Effect.mapError((error) => new StoreError({ reason: `bundle: ${error.reason}` })));
|
|
2392
|
+
if (found !== null) {
|
|
2393
|
+
return HttpServerResponse.empty({
|
|
2394
|
+
status: 200,
|
|
2395
|
+
headers: {
|
|
2396
|
+
...noCache,
|
|
2397
|
+
"content-type": resultType,
|
|
2398
|
+
[BUNDLE_KEY_HEADER]: bundle.key,
|
|
2399
|
+
[BUNDLE_HASH_HEADER]: bundle.refsHash,
|
|
2400
|
+
[BUNDLE_COUNT_HEADER]: String(bundle.objectCount),
|
|
2401
|
+
[BUNDLE_SIDEBAND_HEADER]: sideband ? "1" : "0",
|
|
2402
|
+
},
|
|
2403
|
+
});
|
|
2404
|
+
}
|
|
2405
|
+
}
|
|
2406
|
+
// A depth-limited import leaves the repo itself shallow; those
|
|
2407
|
+
// boundary commits must bound every walk and surface as
|
|
2408
|
+
// `shallow` lines so clones inherit the shallowness (fsck-clean).
|
|
2409
|
+
const shallowRoots = JSON.parse((yield* getConfig("shallow_roots")) ?? "[]");
|
|
2410
|
+
const closureResult = yield* Effect.result(computeClosure({ sql, objects })({
|
|
2411
|
+
wants: req.wants,
|
|
2412
|
+
haves: commons,
|
|
2413
|
+
depth: req.depth,
|
|
2414
|
+
clientShallow: req.clientShallow,
|
|
2415
|
+
repoShallow: shallowRoots,
|
|
2416
|
+
}));
|
|
2417
|
+
if (Result.isFailure(closureResult)) {
|
|
2418
|
+
const error = closureResult.failure;
|
|
2419
|
+
return errResponse(error._tag === "ManifestTooLarge"
|
|
2420
|
+
? `repository too large to serve in one pack (${error.count} > ${error.cap})`
|
|
2421
|
+
: error.reason);
|
|
2422
|
+
}
|
|
2423
|
+
const closure = closureResult.success;
|
|
2424
|
+
// v0 clients only parse a shallow/unshallow section when THEY
|
|
2425
|
+
// brought shallowness into the exchange (`deepen` or `shallow`
|
|
2426
|
+
// lines). If this repo's own boundary truncated the walk for a
|
|
2427
|
+
// client that did neither, an unsolicited section would derail
|
|
2428
|
+
// its parser — refuse cleanly instead.
|
|
2429
|
+
const clientShallowAware = req.depth !== undefined || req.clientShallow.length > 0;
|
|
2430
|
+
if (closure.shallow.length > 0 && !clientShallowAware) {
|
|
2431
|
+
return errResponse("repository has shallow history (imported with depth); clone with --depth");
|
|
2432
|
+
}
|
|
2433
|
+
const head = [];
|
|
2434
|
+
if (clientShallowAware) {
|
|
2435
|
+
for (const oid of closure.shallow) {
|
|
2436
|
+
head.push(pktText(`shallow ${oid}`));
|
|
2437
|
+
}
|
|
2438
|
+
for (const oid of closure.unshallow) {
|
|
2439
|
+
head.push(pktText(`unshallow ${oid}`));
|
|
2440
|
+
}
|
|
2441
|
+
head.push(flushPkt);
|
|
2442
|
+
}
|
|
2443
|
+
// Depth-carrying negotiation round with nothing in common and no
|
|
2444
|
+
// done yet: the response is the shallow section ALONE (lines +
|
|
2445
|
+
// flush) — no NAK, no pack. The stateless client buffers this
|
|
2446
|
+
// response, sends `done`, and expects the NEXT response to begin
|
|
2447
|
+
// with the shallow section again; a trailing NAK here would sit
|
|
2448
|
+
// in its buffer and derail that parse ("expected shallow list").
|
|
2449
|
+
if (!req.done && commons.length === 0) {
|
|
2450
|
+
return HttpServerResponse.uint8Array(concatBytes(head), {
|
|
2451
|
+
contentType: resultType,
|
|
2452
|
+
headers: noCache,
|
|
2453
|
+
});
|
|
2454
|
+
}
|
|
2455
|
+
const lastCommon = commons[commons.length - 1];
|
|
2456
|
+
if (req.done) {
|
|
2457
|
+
head.push(lastCommon === undefined
|
|
2458
|
+
? pktText("NAK")
|
|
2459
|
+
: pktText(`ACK ${lastCommon}`));
|
|
2460
|
+
}
|
|
2461
|
+
else {
|
|
2462
|
+
// !done implies commons.length > 0 (the NAK-only branch above).
|
|
2463
|
+
const ready = lastCommon ?? ZERO_OID;
|
|
2464
|
+
for (const common of commons) {
|
|
2465
|
+
head.push(pktText(`ACK ${common} common`));
|
|
2466
|
+
}
|
|
2467
|
+
head.push(pktText(`ACK ${ready} ready`));
|
|
2468
|
+
if (!noDone) {
|
|
2469
|
+
// Client will re-POST with done; no pack this round.
|
|
2470
|
+
return HttpServerResponse.uint8Array(concatBytes(head), {
|
|
2471
|
+
contentType: resultType,
|
|
2472
|
+
headers: noCache,
|
|
2473
|
+
});
|
|
2474
|
+
}
|
|
2475
|
+
head.push(pktText(`ACK ${ready}`));
|
|
2476
|
+
}
|
|
2477
|
+
// The pack goes out through the native pump (Sideband.ts
|
|
2478
|
+
// `pumpPackBody`, DESIGN §22.3): the emitter's batched chunks are
|
|
2479
|
+
// large, so the Effect→ReadableStream bridge is a handful of
|
|
2480
|
+
// pulls, and framing/flush happen at platform speed.
|
|
2481
|
+
const source = yield* packStream(closure.entries, objects).pipe(Stream.toReadableStreamEffect());
|
|
2482
|
+
const prefix = sideband
|
|
2483
|
+
? concatBytes([
|
|
2484
|
+
concatBytes(head),
|
|
2485
|
+
progressMessage(`Enumerating objects: ${closure.entries.length}, done.`),
|
|
2486
|
+
])
|
|
2487
|
+
: concatBytes(head);
|
|
2488
|
+
return HttpServerResponse.raw(pumpPackBody({ prefix, source, sideband }), { contentType: resultType, headers: noCache });
|
|
2489
|
+
});
|
|
2490
|
+
// ── alarm jobs ───────────────────────────────────────────────────────
|
|
2491
|
+
/** Nulls a committed push's `staged_push` column and drops its row. */
|
|
2492
|
+
const flipPush = (pushId) => Effect.gen(function* () {
|
|
2493
|
+
yield* sql.run(`UPDATE objects SET staged_push = NULL WHERE staged_push = ?`, pushId);
|
|
2494
|
+
yield* sql.run(`DELETE FROM pushes WHERE push_id = ? AND state = 'committed'`, pushId);
|
|
2495
|
+
});
|
|
2496
|
+
const runGcJob = Effect.gen(function* () {
|
|
2497
|
+
// Committed pushes whose deferred flip never ran (DESIGN §22.14).
|
|
2498
|
+
yield* sql.run(`UPDATE objects SET staged_push = NULL WHERE staged_push IN
|
|
2499
|
+
(SELECT push_id FROM pushes WHERE state = 'committed')`);
|
|
2500
|
+
yield* sql.run(`DELETE FROM pushes WHERE state = 'committed'`);
|
|
2501
|
+
const cutoff = Date.now() - STAGING_TTL_MS;
|
|
2502
|
+
yield* sql.run(`DELETE FROM objects WHERE staged_push IN
|
|
2503
|
+
(SELECT push_id FROM pushes WHERE state = 'staging' AND started_at < ?)`, cutoff);
|
|
2504
|
+
yield* sql.run(`DELETE FROM pushes WHERE state = 'staging' AND started_at < ?`, cutoff);
|
|
2505
|
+
yield* sql.run(`DELETE FROM jobs WHERE kind = 'gc'`);
|
|
2506
|
+
});
|
|
2507
|
+
/**
|
|
2508
|
+
* Compaction (DESIGN.md §12.1): moves loose object bytes out of DO
|
|
2509
|
+
* SQLite into an immutable R2 pack, bounded per run and re-armed
|
|
2510
|
+
* while more remain.
|
|
2511
|
+
*/
|
|
2512
|
+
const runCompactAlarm = Effect.gen(function* () {
|
|
2513
|
+
const meta = yield* requireMeta;
|
|
2514
|
+
// Grace-delete packs a PREVIOUS merge unreferenced: only after
|
|
2515
|
+
// a minute, so any read planned before that row flip has long
|
|
2516
|
+
// finished its ranged reads (DESIGN.md §21).
|
|
2517
|
+
const pendingRaw = yield* getConfig("packs_pending_delete");
|
|
2518
|
+
const pending = pendingRaw === undefined || pendingRaw === ""
|
|
2519
|
+
? undefined
|
|
2520
|
+
: JSON.parse(pendingRaw);
|
|
2521
|
+
if (pending !== undefined && Date.now() - pending.at > 60_000) {
|
|
2522
|
+
yield* blobs
|
|
2523
|
+
.delete(pending.keys)
|
|
2524
|
+
.pipe(Effect.catch(() => Effect.void));
|
|
2525
|
+
yield* setConfig("packs_pending_delete", "");
|
|
2526
|
+
}
|
|
2527
|
+
const outcome = yield* runCompactJob({
|
|
2528
|
+
repoId: meta.repoId,
|
|
2529
|
+
sql,
|
|
2530
|
+
blobs,
|
|
2531
|
+
});
|
|
2532
|
+
// Restore the geometric invariant over the repo's packs, so pack
|
|
2533
|
+
// count — and with it read fan-out — stays O(log bytes).
|
|
2534
|
+
const merge = yield* runGeometricMergeJob({
|
|
2535
|
+
repoId: meta.repoId,
|
|
2536
|
+
sql,
|
|
2537
|
+
blobs,
|
|
2538
|
+
});
|
|
2539
|
+
if (merge.pendingDelete.length > 0) {
|
|
2540
|
+
const carried = pending !== undefined && !(Date.now() - pending.at > 60_000)
|
|
2541
|
+
? pending.keys
|
|
2542
|
+
: [];
|
|
2543
|
+
yield* setConfig("packs_pending_delete", JSON.stringify({
|
|
2544
|
+
keys: [...carried, ...merge.pendingDelete],
|
|
2545
|
+
at: Date.now(),
|
|
2546
|
+
}));
|
|
2547
|
+
}
|
|
2548
|
+
if (outcome.more || merge.more) {
|
|
2549
|
+
yield* armAlarmAt(Date.now() + 1_000);
|
|
2550
|
+
return;
|
|
2551
|
+
}
|
|
2552
|
+
yield* sql.run(`DELETE FROM jobs WHERE kind = 'compact'`);
|
|
2553
|
+
});
|
|
2554
|
+
/** The repo's current clone bundle, if one has been cut. */
|
|
2555
|
+
/**
|
|
2556
|
+
* Pushes the denormalised display fields to the Registry so listing
|
|
2557
|
+
* repos never has to wake this DO (DESIGN.md §15 bottleneck 7).
|
|
2558
|
+
* Best-effort: the DO remains the source of truth, and a failed
|
|
2559
|
+
* refresh only makes a listing momentarily stale.
|
|
2560
|
+
*/
|
|
2561
|
+
const syncSummary = Effect.fn(function* (meta) {
|
|
2562
|
+
yield* registry
|
|
2563
|
+
.updateSummary(meta.repoId, {
|
|
2564
|
+
defaultBranch: meta.defaultBranch,
|
|
2565
|
+
readOnly: meta.readOnly,
|
|
2566
|
+
status: meta.status,
|
|
2567
|
+
public: meta.public,
|
|
2568
|
+
})
|
|
2569
|
+
.pipe(Effect.ignore);
|
|
2570
|
+
});
|
|
2571
|
+
/** Re-reads metadata and refreshes the Registry summary. */
|
|
2572
|
+
const refreshSummary = readMeta.pipe(Effect.flatMap((meta) => meta === undefined ? Effect.void : syncSummary(meta)), Effect.ignore);
|
|
2573
|
+
const readBundle = getConfig("bundle").pipe(Effect.map((value) => value === undefined ? undefined : JSON.parse(value)));
|
|
2574
|
+
/**
|
|
2575
|
+
* Republishes the repo's head snapshot (DESIGN.md §21): a tiny
|
|
2576
|
+
* JSON object in the BlobStore from which the Worker serves
|
|
2577
|
+
* anonymous public reads — the upload-pack advertisement and
|
|
2578
|
+
* bundle-covered clones — without waking this DO. Called after
|
|
2579
|
+
* every commit that changes what an anonymous reader can see.
|
|
2580
|
+
*
|
|
2581
|
+
* Best-effort by design: it runs AFTER the SQLite commit (which
|
|
2582
|
+
* stays authoritative), so a failed write only leaves a stale
|
|
2583
|
+
* snapshot that the next mutation — or the post-push bundle
|
|
2584
|
+
* alarm, seconds later — repairs.
|
|
2585
|
+
*/
|
|
2586
|
+
const writeHeadSnapshot = Effect.gen(function* () {
|
|
2587
|
+
const meta = yield* requireMeta;
|
|
2588
|
+
const refs = yield* listAllRefs(meta.repoId);
|
|
2589
|
+
const bundle = yield* readBundle;
|
|
2590
|
+
const snapshot = {
|
|
2591
|
+
v: 1,
|
|
2592
|
+
repoId: meta.repoId,
|
|
2593
|
+
owner: meta.owner,
|
|
2594
|
+
name: meta.name,
|
|
2595
|
+
public: meta.public,
|
|
2596
|
+
readOnly: meta.readOnly,
|
|
2597
|
+
defaultBranch: meta.defaultBranch,
|
|
2598
|
+
refs,
|
|
2599
|
+
bundle,
|
|
2600
|
+
};
|
|
2601
|
+
yield* blobs.put(headKey(meta.repoId), utf8Encode(encodeHeadSnapshot(snapshot)));
|
|
2602
|
+
}).pipe(Effect.catch((error) => Effect.logWarning(`head snapshot write failed: ${String(error)}`)), Effect.asVoid);
|
|
2603
|
+
/**
|
|
2604
|
+
* Cuts a clone bundle for the current refs (DESIGN.md §12.2) so future
|
|
2605
|
+
* clones are served as bytes from R2 instead of a fresh closure walk.
|
|
2606
|
+
*/
|
|
2607
|
+
const runBundleAlarm = Effect.gen(function* () {
|
|
2608
|
+
const meta = yield* requireMeta;
|
|
2609
|
+
const objects = storeFor(meta.repoId);
|
|
2610
|
+
const refRows = yield* sql.all(`SELECT name, oid FROM refs ORDER BY name`);
|
|
2611
|
+
const shallowRoots = JSON.parse((yield* getConfig("shallow_roots")) ?? "[]");
|
|
2612
|
+
const closure = yield* computeClosure({ sql, objects })({
|
|
2613
|
+
wants: refRows.map((ref) => ref.oid),
|
|
2614
|
+
haves: [],
|
|
2615
|
+
clientShallow: [],
|
|
2616
|
+
repoShallow: shallowRoots,
|
|
2617
|
+
}).pipe(Effect.catchTag("ManifestTooLarge", (error) => Effect.fail(new StoreError({ reason: `bundle: ${error._tag}` }))));
|
|
2618
|
+
const info = yield* runBundleJob({
|
|
2619
|
+
repoId: meta.repoId,
|
|
2620
|
+
refs: refRows.map((ref) => ({ name: ref.name, oid: ref.oid })),
|
|
2621
|
+
entries: closure.entries,
|
|
2622
|
+
packStream: (entries) => packStream(entries, objects),
|
|
2623
|
+
blobs,
|
|
2624
|
+
});
|
|
2625
|
+
if (info !== undefined) {
|
|
2626
|
+
yield* setConfig("bundle", JSON.stringify(info));
|
|
2627
|
+
// The snapshot now names a bundle covering the current refs —
|
|
2628
|
+
// full anonymous clones go DO-less from here (DESIGN.md §21).
|
|
2629
|
+
yield* writeHeadSnapshot;
|
|
2630
|
+
}
|
|
2631
|
+
yield* sql.run(`DELETE FROM jobs WHERE kind = 'bundle'`);
|
|
2632
|
+
});
|
|
2633
|
+
const runImportAlarm = (job) => Effect.gen(function* () {
|
|
2634
|
+
const meta = yield* requireMeta;
|
|
2635
|
+
const detail = JSON.parse(job.detail ?? "{}");
|
|
2636
|
+
const attempts = detail.attempts ?? 0;
|
|
2637
|
+
const outcome = yield* Effect.result(runImport({ source: detail.source }).pipe(Effect.provide(FetchHttpClient.layer)));
|
|
2638
|
+
if (Result.isFailure(outcome)) {
|
|
2639
|
+
if (attempts + 1 >= 3) {
|
|
2640
|
+
yield* sql.run(`UPDATE jobs SET state = 'failed', detail = ?, updated_at = ? WHERE kind = 'import'`, JSON.stringify({ ...detail, error: outcome.failure.reason }), Date.now());
|
|
2641
|
+
// Give the empty repo back rather than wedging in 'importing'.
|
|
2642
|
+
yield* setConfig("status", "ready");
|
|
2643
|
+
yield* refreshSummary;
|
|
2644
|
+
yield* refreshSummary;
|
|
2645
|
+
return;
|
|
2646
|
+
}
|
|
2647
|
+
yield* sql.run(`UPDATE jobs SET detail = ?, updated_at = ? WHERE kind = 'import'`, JSON.stringify({ ...detail, attempts: attempts + 1 }), Date.now());
|
|
2648
|
+
yield* armAlarmAt(Date.now() + 15_000);
|
|
2649
|
+
return;
|
|
2650
|
+
}
|
|
2651
|
+
const result = outcome.success;
|
|
2652
|
+
const objects = storeFor(meta.repoId);
|
|
2653
|
+
const pushId = yield* ulid();
|
|
2654
|
+
// Imports use the same staging lifecycle as pushes: finalize
|
|
2655
|
+
// requires an active row, and GC needs it to reap abandoned data.
|
|
2656
|
+
yield* sql.run(`INSERT INTO pushes (push_id, started_at, state) VALUES (?, ?, 'staging')`, pushId, Date.now());
|
|
2657
|
+
yield* upsertJob("gc", null);
|
|
2658
|
+
yield* armAlarmAt(Date.now() + STAGING_TTL_MS);
|
|
2659
|
+
let graph = [];
|
|
2660
|
+
if (result.pack !== undefined) {
|
|
2661
|
+
const ingest = yield* ingestPack(result.pack, {
|
|
2662
|
+
store: objects,
|
|
2663
|
+
pushId,
|
|
2664
|
+
allowMissingParents: true,
|
|
2665
|
+
}).pipe(Effect.mapError((error) => new StoreError({
|
|
2666
|
+
reason: error._tag === "PackIngestError"
|
|
2667
|
+
? `import ingest: ${error.reason}`
|
|
2668
|
+
: error.reason,
|
|
2669
|
+
})));
|
|
2670
|
+
// Connectivity: hard edges only — shallow imports may lack
|
|
2671
|
+
// parent commits (they become walk boundaries).
|
|
2672
|
+
const missing = yield* objects.missingObjects([...ingest.referenced], pushId);
|
|
2673
|
+
if (missing.length > 0) {
|
|
2674
|
+
return yield* new StoreError({
|
|
2675
|
+
reason: `import produced ${missing.length} dangling objects`,
|
|
2676
|
+
});
|
|
2677
|
+
}
|
|
2678
|
+
graph = yield* computeGraphRows(ingest.commits);
|
|
2679
|
+
// A depth-limited import leaves parents un-ingested: record the
|
|
2680
|
+
// boundary commits so upload-pack serves this repo as shallow
|
|
2681
|
+
// (walk bound + `shallow` lines — see handleUploadPack).
|
|
2682
|
+
const parentOids = Array.from(new Set(ingest.commits.flatMap((commit) => commit.parents)));
|
|
2683
|
+
const missingParents = new Set(yield* objects.missingObjects(parentOids, pushId));
|
|
2684
|
+
if (missingParents.size > 0) {
|
|
2685
|
+
const shallowRoots = ingest.commits
|
|
2686
|
+
.filter((commit) => commit.parents.some((parent) => missingParents.has(parent)))
|
|
2687
|
+
.map((commit) => commit.oid);
|
|
2688
|
+
yield* setConfig("shallow_roots", JSON.stringify(shallowRoots));
|
|
2689
|
+
}
|
|
2690
|
+
}
|
|
2691
|
+
const commands = result.refs.map((ref) => ({
|
|
2692
|
+
oldOid: ZERO_OID,
|
|
2693
|
+
newOid: ref.oid,
|
|
2694
|
+
ref: ref.name,
|
|
2695
|
+
}));
|
|
2696
|
+
const results = yield* finalizeRefTxn({
|
|
2697
|
+
commands,
|
|
2698
|
+
atomic: false,
|
|
2699
|
+
unconditional: true,
|
|
2700
|
+
pushId,
|
|
2701
|
+
graph,
|
|
2702
|
+
});
|
|
2703
|
+
const rejected = results.find((ref) => !ref.ok);
|
|
2704
|
+
if (rejected !== undefined) {
|
|
2705
|
+
return yield* new StoreError({
|
|
2706
|
+
reason: `import ref ${rejected.ref}: ${rejected.reason}`,
|
|
2707
|
+
});
|
|
2708
|
+
}
|
|
2709
|
+
yield* flipPush(pushId);
|
|
2710
|
+
if (result.defaultBranch !== null) {
|
|
2711
|
+
yield* setConfig("default_branch", result.defaultBranch);
|
|
2712
|
+
}
|
|
2713
|
+
yield* setConfig("status", "ready");
|
|
2714
|
+
yield* refreshSummary;
|
|
2715
|
+
yield* writeHeadSnapshot;
|
|
2716
|
+
yield* sql.run(`DELETE FROM jobs WHERE kind = 'import'`);
|
|
2717
|
+
});
|
|
2718
|
+
const runForkAlarm = (job) => Effect.gen(function* () {
|
|
2719
|
+
const detail = JSON.parse(job.detail ?? "{}");
|
|
2720
|
+
const parentStub = selfNamespace.getByName(detail.parentRepoId);
|
|
2721
|
+
const applied = yield* Effect.result(runForkJob({
|
|
2722
|
+
sql,
|
|
2723
|
+
snapshot: parentStub.snapshotRows(),
|
|
2724
|
+
}));
|
|
2725
|
+
if (Result.isFailure(applied)) {
|
|
2726
|
+
const attempts = (detail.attempts ?? 0) + 1;
|
|
2727
|
+
if (attempts >= 3) {
|
|
2728
|
+
yield* sql.run(`UPDATE jobs SET state = 'failed', detail = ?, updated_at = ? WHERE kind = 'fork'`, JSON.stringify({ ...detail, error: applied.failure.reason }), Date.now());
|
|
2729
|
+
yield* setConfig("status", "ready");
|
|
2730
|
+
yield* refreshSummary;
|
|
2731
|
+
yield* refreshSummary;
|
|
2732
|
+
return;
|
|
2733
|
+
}
|
|
2734
|
+
yield* sql.run(`UPDATE jobs SET detail = ?, updated_at = ? WHERE kind = 'fork'`, JSON.stringify({ ...detail, attempts }), Date.now());
|
|
2735
|
+
yield* armAlarmAt(Date.now() + 15_000);
|
|
2736
|
+
return;
|
|
2737
|
+
}
|
|
2738
|
+
yield* setConfig("status", "ready");
|
|
2739
|
+
yield* refreshSummary;
|
|
2740
|
+
yield* writeHeadSnapshot;
|
|
2741
|
+
yield* sql.run(`DELETE FROM jobs WHERE kind = 'fork'`);
|
|
2742
|
+
});
|
|
2743
|
+
/** Returns true when storage was wiped (stop touching SQLite). */
|
|
2744
|
+
const runPurgeAlarm = Effect.gen(function* () {
|
|
2745
|
+
const meta = yield* readMeta;
|
|
2746
|
+
if (meta === undefined)
|
|
2747
|
+
return true;
|
|
2748
|
+
const registryStub = registry;
|
|
2749
|
+
const outcome = yield* runPurgeJob({
|
|
2750
|
+
repoId: meta.repoId,
|
|
2751
|
+
blobs,
|
|
2752
|
+
// RuntimeContext is genuinely satisfied here (we run inside the
|
|
2753
|
+
// DO); discharge the coloring so the purge job's deps stay R=never.
|
|
2754
|
+
forkCount: registryStub.bumpForkCount(meta.repoId, 0).pipe(Effect.mapError((error) => new StoreError({ reason: String(error) })), Effect.provide(RuntimeContext.phantom)),
|
|
2755
|
+
deleteAllStorage: state.storage.deleteAll().pipe(Effect.mapError((error) => new StoreError({ reason: String(error) })), Effect.provide(RuntimeContext.phantom)),
|
|
2756
|
+
removeRegistryRow: registryStub.removeRow(meta.repoId).pipe(Effect.mapError((error) => new StoreError({ reason: String(error) })), Effect.provide(RuntimeContext.phantom)),
|
|
2757
|
+
});
|
|
2758
|
+
if (outcome._tag === "continue") {
|
|
2759
|
+
yield* armAlarmAt(Date.now() + (outcome.forkPinned ? 60_000 : 5_000));
|
|
2760
|
+
return false;
|
|
2761
|
+
}
|
|
2762
|
+
yield* state.storage.deleteAlarm();
|
|
2763
|
+
return true;
|
|
2764
|
+
});
|
|
2765
|
+
// ── the shape ────────────────────────────────────────────────────────
|
|
2766
|
+
const shape = {
|
|
2767
|
+
initRepo: (input) => bootstrap(input, "ready").pipe(Effect.tap(() => writeHeadSnapshot)),
|
|
2768
|
+
startImport: Effect.fn(function* (input) {
|
|
2769
|
+
const result = yield* bootstrap(input, "importing");
|
|
2770
|
+
yield* upsertJob("import", JSON.stringify({ source: input.source }));
|
|
2771
|
+
yield* armAlarmAt(Date.now());
|
|
2772
|
+
return result;
|
|
2773
|
+
}),
|
|
2774
|
+
startFork: Effect.fn(function* (input) {
|
|
2775
|
+
const result = yield* bootstrap(input, "forking");
|
|
2776
|
+
yield* upsertJob("fork", JSON.stringify({ parentRepoId: input.parentRepoId }));
|
|
2777
|
+
yield* armAlarmAt(Date.now());
|
|
2778
|
+
return result;
|
|
2779
|
+
}),
|
|
2780
|
+
startCompact: Effect.fn(function* () {
|
|
2781
|
+
yield* requireMeta;
|
|
2782
|
+
yield* upsertJob("compact", null);
|
|
2783
|
+
yield* armAlarmAt(Date.now());
|
|
2784
|
+
}),
|
|
2785
|
+
startPurge: Effect.fn(function* () {
|
|
2786
|
+
const meta = yield* requireMeta;
|
|
2787
|
+
yield* setConfig("status", "deleting");
|
|
2788
|
+
// Kill the DO-less fast path NOW — the prefix drain gets the
|
|
2789
|
+
// rest, but anonymous reads must stop serving immediately.
|
|
2790
|
+
yield* blobs
|
|
2791
|
+
.delete(headKey(meta.repoId))
|
|
2792
|
+
.pipe(Effect.catch(() => Effect.void));
|
|
2793
|
+
yield* refreshSummary;
|
|
2794
|
+
yield* upsertJob("purge", null);
|
|
2795
|
+
yield* armAlarmAt(Date.now());
|
|
2796
|
+
}),
|
|
2797
|
+
getRepoMeta: Effect.fn(function* () {
|
|
2798
|
+
const meta = yield* requireMetaStats;
|
|
2799
|
+
return meta;
|
|
2800
|
+
}),
|
|
2801
|
+
readMeta: Effect.fn(function* () {
|
|
2802
|
+
return yield* requireMetaStats;
|
|
2803
|
+
}),
|
|
2804
|
+
updateRepoMeta: Effect.fn(function* (patch) {
|
|
2805
|
+
const meta = yield* requireMeta;
|
|
2806
|
+
if (patch.defaultBranch !== undefined) {
|
|
2807
|
+
const ref = yield* sql.first(`SELECT name, oid FROM refs WHERE name = ?`, `refs/heads/${patch.defaultBranch}`);
|
|
2808
|
+
if (ref === undefined) {
|
|
2809
|
+
return yield* new RefNotFound({
|
|
2810
|
+
ref: `refs/heads/${patch.defaultBranch}`,
|
|
2811
|
+
});
|
|
2812
|
+
}
|
|
2813
|
+
yield* setConfig("default_branch", patch.defaultBranch);
|
|
2814
|
+
}
|
|
2815
|
+
if (patch.description !== undefined) {
|
|
2816
|
+
if (patch.description === null) {
|
|
2817
|
+
yield* sql.run(`DELETE FROM config WHERE key = 'description'`);
|
|
2818
|
+
}
|
|
2819
|
+
else {
|
|
2820
|
+
yield* setConfig("description", patch.description);
|
|
2821
|
+
}
|
|
2822
|
+
}
|
|
2823
|
+
if (patch.readOnly !== undefined) {
|
|
2824
|
+
yield* setConfig("read_only", patch.readOnly ? "1" : "0");
|
|
2825
|
+
}
|
|
2826
|
+
if (patch.public !== undefined) {
|
|
2827
|
+
yield* setConfig("public", patch.public ? "1" : "0");
|
|
2828
|
+
}
|
|
2829
|
+
const updated = yield* readMetaStats;
|
|
2830
|
+
const result = updated ?? meta;
|
|
2831
|
+
// Keep the Registry's denormalised copy in step (listing reads it).
|
|
2832
|
+
yield* syncSummary(result);
|
|
2833
|
+
yield* writeHeadSnapshot;
|
|
2834
|
+
return result;
|
|
2835
|
+
}),
|
|
2836
|
+
listRefs: Effect.fn(function* (prefix) {
|
|
2837
|
+
const meta = yield* requireMeta;
|
|
2838
|
+
const refs = yield* listAllRefs(meta.repoId, prefix);
|
|
2839
|
+
const headRef = `refs/heads/${meta.defaultBranch}`;
|
|
2840
|
+
const headExists = yield* sql.first(`SELECT name, oid FROM refs WHERE name = ?`, headRef);
|
|
2841
|
+
return {
|
|
2842
|
+
head: headExists === undefined ? null : headRef,
|
|
2843
|
+
refs,
|
|
2844
|
+
};
|
|
2845
|
+
}),
|
|
2846
|
+
getRef: Effect.fn(function* (name) {
|
|
2847
|
+
const meta = yield* requireMeta;
|
|
2848
|
+
const row = yield* sql.first(`SELECT name, oid FROM refs WHERE name = ?`, name);
|
|
2849
|
+
if (row === undefined) {
|
|
2850
|
+
return yield* new RefNotFound({ ref: name });
|
|
2851
|
+
}
|
|
2852
|
+
const peeled = name.startsWith("refs/tags/")
|
|
2853
|
+
? yield* peelOid(meta.repoId, row.oid)
|
|
2854
|
+
: undefined;
|
|
2855
|
+
return peeled === undefined
|
|
2856
|
+
? { name: row.name, oid: row.oid }
|
|
2857
|
+
: { name: row.name, oid: row.oid, peeled };
|
|
2858
|
+
}),
|
|
2859
|
+
updateRef: Effect.fn(function* (input) {
|
|
2860
|
+
const meta = yield* requireMeta;
|
|
2861
|
+
if (meta.readOnly) {
|
|
2862
|
+
return yield* new ReadOnlyRepo();
|
|
2863
|
+
}
|
|
2864
|
+
const objects = storeFor(meta.repoId);
|
|
2865
|
+
const exists = yield* objects.has(input.newOid);
|
|
2866
|
+
if (!exists) {
|
|
2867
|
+
return yield* new ObjectNotFound({ oid: input.newOid });
|
|
2868
|
+
}
|
|
2869
|
+
yield* sql.transactionSync((raw, rollback) => {
|
|
2870
|
+
const rows = raw
|
|
2871
|
+
.exec(`SELECT name, oid FROM refs WHERE name = ?`, input.name)
|
|
2872
|
+
.toArray();
|
|
2873
|
+
const current = rows.length > 0 ? rows[0].oid : null;
|
|
2874
|
+
if (input.expectedOid !== undefined) {
|
|
2875
|
+
const expected = input.expectedOid; // string | null
|
|
2876
|
+
if (current !== expected) {
|
|
2877
|
+
rollback(new RefConflict({
|
|
2878
|
+
ref: input.name,
|
|
2879
|
+
currentOid: current === null ? null : asOid(current),
|
|
2880
|
+
}));
|
|
2881
|
+
}
|
|
2882
|
+
}
|
|
2883
|
+
raw.exec(`INSERT INTO refs (name, oid) VALUES (?, ?)
|
|
2884
|
+
ON CONFLICT (name) DO UPDATE SET oid = excluded.oid`, input.name, input.newOid);
|
|
2885
|
+
});
|
|
2886
|
+
yield* writeHeadSnapshot;
|
|
2887
|
+
return { name: input.name, oid: input.newOid };
|
|
2888
|
+
}),
|
|
2889
|
+
removeRef: Effect.fn(function* (input) {
|
|
2890
|
+
const meta = yield* requireMeta;
|
|
2891
|
+
if (meta.readOnly) {
|
|
2892
|
+
return yield* new ReadOnlyRepo();
|
|
2893
|
+
}
|
|
2894
|
+
yield* sql.transactionSync((raw, rollback) => {
|
|
2895
|
+
const rows = raw
|
|
2896
|
+
.exec(`SELECT name, oid FROM refs WHERE name = ?`, input.name)
|
|
2897
|
+
.toArray();
|
|
2898
|
+
if (rows.length === 0) {
|
|
2899
|
+
rollback(new RefNotFound({ ref: input.name }));
|
|
2900
|
+
}
|
|
2901
|
+
const current = rows[0].oid;
|
|
2902
|
+
if (input.expectedOid !== undefined &&
|
|
2903
|
+
current !== input.expectedOid) {
|
|
2904
|
+
rollback(new RefConflict({
|
|
2905
|
+
ref: input.name,
|
|
2906
|
+
currentOid: asOid(current),
|
|
2907
|
+
}));
|
|
2908
|
+
}
|
|
2909
|
+
raw.exec(`DELETE FROM refs WHERE name = ?`, input.name);
|
|
2910
|
+
});
|
|
2911
|
+
yield* writeHeadSnapshot;
|
|
2912
|
+
}),
|
|
2913
|
+
beginPush: Effect.fn(function* (input) {
|
|
2914
|
+
const meta = yield* requireMeta;
|
|
2915
|
+
if (meta.readOnly) {
|
|
2916
|
+
return {
|
|
2917
|
+
_tag: "denied",
|
|
2918
|
+
reason: "repository is read-only",
|
|
2919
|
+
};
|
|
2920
|
+
}
|
|
2921
|
+
const pushId = yield* ulid();
|
|
2922
|
+
yield* sql.run(`INSERT INTO pushes (push_id, started_at, state) VALUES (?, ?, 'staging')`, pushId, Date.now());
|
|
2923
|
+
return { _tag: "ok", pushId };
|
|
2924
|
+
}),
|
|
2925
|
+
stagePush: Effect.fn(function* (pushId, batch) {
|
|
2926
|
+
const meta = yield* requireMeta;
|
|
2927
|
+
yield* storeFor(meta.repoId).insertStagedBatch(pushId, decodeStagedBatch(batch));
|
|
2928
|
+
}),
|
|
2929
|
+
abortPush: Effect.fn(function* (pushId, packIds = []) {
|
|
2930
|
+
yield* requireMeta;
|
|
2931
|
+
return yield* sql.transactionSync((raw) => {
|
|
2932
|
+
const push = raw
|
|
2933
|
+
.exec(`SELECT state FROM pushes WHERE push_id = ?`, pushId)
|
|
2934
|
+
.toArray()[0];
|
|
2935
|
+
if (push?.state === "committed")
|
|
2936
|
+
return false;
|
|
2937
|
+
raw.exec(`DELETE FROM objects WHERE staged_push = ?`, pushId);
|
|
2938
|
+
raw.exec(`DELETE FROM pushes WHERE push_id = ? AND state = 'staging'`, pushId);
|
|
2939
|
+
// Another concurrent push may have adopted staged rows. Retain any
|
|
2940
|
+
// shared pack bytes even though this transaction has been aborted.
|
|
2941
|
+
for (const packId of packIds) {
|
|
2942
|
+
if (raw
|
|
2943
|
+
.exec(`SELECT 1 FROM objects WHERE pack_id = ? LIMIT 1`, packId)
|
|
2944
|
+
.toArray().length > 0)
|
|
2945
|
+
return false;
|
|
2946
|
+
}
|
|
2947
|
+
return true;
|
|
2948
|
+
});
|
|
2949
|
+
}),
|
|
2950
|
+
validatePush: Effect.fn(function* (input) {
|
|
2951
|
+
const meta = yield* requireMeta;
|
|
2952
|
+
const referenced = new Set([
|
|
2953
|
+
...input.referenced,
|
|
2954
|
+
...input.referencedParents,
|
|
2955
|
+
]);
|
|
2956
|
+
for (const command of input.commands)
|
|
2957
|
+
if (command.newOid !== ZERO_OID)
|
|
2958
|
+
referenced.add(command.newOid);
|
|
2959
|
+
const missing = yield* storeFor(meta.repoId).missingObjects(Array.from(referenced), input.pushId);
|
|
2960
|
+
if (missing.length > 0)
|
|
2961
|
+
return yield* new StoreError({
|
|
2962
|
+
reason: `missing objects (${missing.length})`,
|
|
2963
|
+
});
|
|
2964
|
+
}),
|
|
2965
|
+
readPreparedObject: Effect.fn(function* (pushId, oid, maxBytes) {
|
|
2966
|
+
const meta = yield* requireMeta;
|
|
2967
|
+
const push = yield* sql.first(`SELECT state FROM pushes WHERE push_id = ?`, pushId);
|
|
2968
|
+
if (push?.state !== "staging")
|
|
2969
|
+
return yield* new StoreError({
|
|
2970
|
+
reason: "push is no longer active",
|
|
2971
|
+
});
|
|
2972
|
+
return yield* storeFor(meta.repoId).readPrepared(pushId, oid, maxBytes);
|
|
2973
|
+
}),
|
|
2974
|
+
readPushBase: Effect.fn(function* (oid) {
|
|
2975
|
+
const meta = yield* requireMeta;
|
|
2976
|
+
return yield* ingestStoreOf(storeFor(meta.repoId)).readBase(oid);
|
|
2977
|
+
}),
|
|
2978
|
+
commitPush: Effect.fn(function* (input) {
|
|
2979
|
+
const meta = yield* requireMeta;
|
|
2980
|
+
const objects = storeFor(meta.repoId);
|
|
2981
|
+
const startedAt = yield* Effect.sync(() => performance.now());
|
|
2982
|
+
const since = (from) => Effect.sync(() => performance.now() - from);
|
|
2983
|
+
const allNg = (reason) => input.commands.map((cmd) => ({
|
|
2984
|
+
ref: cmd.ref,
|
|
2985
|
+
ok: false,
|
|
2986
|
+
reason,
|
|
2987
|
+
}));
|
|
2988
|
+
if (meta.readOnly)
|
|
2989
|
+
return { unpack: "ok", results: allNg("repository is read-only") };
|
|
2990
|
+
// Full connectivity check (§3.6 step 5) over the staged rows.
|
|
2991
|
+
const referenced = new Set(input.referenced);
|
|
2992
|
+
for (const parent of input.referencedParents)
|
|
2993
|
+
referenced.add(parent);
|
|
2994
|
+
for (const cmd of input.commands) {
|
|
2995
|
+
if (cmd.newOid !== ZERO_OID)
|
|
2996
|
+
referenced.add(cmd.newOid);
|
|
2997
|
+
}
|
|
2998
|
+
const connectivityStarted = yield* Effect.sync(() => performance.now());
|
|
2999
|
+
const missing = yield* objects.missingObjects(Array.from(referenced), input.pushId);
|
|
3000
|
+
const connectivityMs = yield* since(connectivityStarted);
|
|
3001
|
+
if (missing.length > 0) {
|
|
3002
|
+
return {
|
|
3003
|
+
unpack: `missing objects (${missing.length})`,
|
|
3004
|
+
results: allNg("missing necessary objects"),
|
|
3005
|
+
};
|
|
3006
|
+
}
|
|
3007
|
+
const graph = yield* computeGraphRows(input.commits);
|
|
3008
|
+
const finalizeStarted = yield* Effect.sync(() => performance.now());
|
|
3009
|
+
const results = yield* finalizeRefTxn({
|
|
3010
|
+
commands: input.commands,
|
|
3011
|
+
atomic: input.atomic,
|
|
3012
|
+
pushId: input.pushId,
|
|
3013
|
+
deferFlip: true,
|
|
3014
|
+
graph,
|
|
3015
|
+
});
|
|
3016
|
+
const finalizeMs = yield* since(finalizeStarted);
|
|
3017
|
+
// The per-row flip, off the response path (DESIGN §22.14).
|
|
3018
|
+
yield* state.waitUntil(flipPush(input.pushId).pipe(Effect.ignore));
|
|
3019
|
+
yield* setConfig("last_push", JSON.stringify({
|
|
3020
|
+
objects: input.stats.objects,
|
|
3021
|
+
bytes: input.stats.bytes,
|
|
3022
|
+
ingestMs: Math.round(input.stats.ingestMs),
|
|
3023
|
+
phases: input.stats.phases === undefined
|
|
3024
|
+
? undefined
|
|
3025
|
+
: Object.fromEntries(Object.entries(input.stats.phases).map(([k, v]) => [
|
|
3026
|
+
k,
|
|
3027
|
+
Math.round(v),
|
|
3028
|
+
])),
|
|
3029
|
+
stageMs: Math.round(input.stats.stageMs),
|
|
3030
|
+
connectivityMs: Math.round(connectivityMs),
|
|
3031
|
+
finalizeMs: Math.round(finalizeMs),
|
|
3032
|
+
totalMs: Math.round(yield* since(startedAt)),
|
|
3033
|
+
})).pipe(Effect.ignore);
|
|
3034
|
+
// Post-commit bookkeeping off the response path: staged-row GC
|
|
3035
|
+
// and, once enough loose bytes have accumulated, compaction into
|
|
3036
|
+
// an R2 pack (DESIGN.md §12.1).
|
|
3037
|
+
yield* state.waitUntil(upsertJob("gc", null).pipe(Effect.flatMap(() => armAlarmAt(Date.now() + STAGING_TTL_MS)), Effect.flatMap(() => shouldCompact(sql)), Effect.flatMap((due) => due
|
|
3038
|
+
? upsertJob("compact", null).pipe(Effect.flatMap(() => armAlarmAt(Date.now() + 1_000)))
|
|
3039
|
+
: Effect.void),
|
|
3040
|
+
// Re-cut the clone bundle for the new ref snapshot. Debounced
|
|
3041
|
+
// by the alarm itself: rapid-fire pushes coalesce into one
|
|
3042
|
+
// run because the job row is upserted, not queued.
|
|
3043
|
+
Effect.flatMap(() => upsertJob("bundle", null)), Effect.flatMap(() => armAlarmAt(Date.now() + 2_000)), Effect.ignore));
|
|
3044
|
+
return { unpack: "ok", results };
|
|
3045
|
+
}),
|
|
3046
|
+
readObject: Effect.fn(function* (input) {
|
|
3047
|
+
const meta = yield* requireMeta;
|
|
3048
|
+
const objects = storeFor(meta.repoId);
|
|
3049
|
+
const objectMeta = yield* objects.getMeta(input.oid);
|
|
3050
|
+
if (objectMeta === undefined) {
|
|
3051
|
+
return yield* new ObjectNotFound({ oid: input.oid });
|
|
3052
|
+
}
|
|
3053
|
+
const actual = objectTypeName(objectMeta.type);
|
|
3054
|
+
if (input.expect !== undefined && actual !== input.expect) {
|
|
3055
|
+
return yield* new WrongObjectType({
|
|
3056
|
+
oid: input.oid,
|
|
3057
|
+
expected: input.expect,
|
|
3058
|
+
actual,
|
|
3059
|
+
});
|
|
3060
|
+
}
|
|
3061
|
+
const content = yield* objects.readContent(input.oid);
|
|
3062
|
+
return {
|
|
3063
|
+
oid: input.oid,
|
|
3064
|
+
type: actual,
|
|
3065
|
+
size: objectMeta.size,
|
|
3066
|
+
content,
|
|
3067
|
+
};
|
|
3068
|
+
}),
|
|
3069
|
+
readCommitLog: Effect.fn(function* (input) {
|
|
3070
|
+
const meta = yield* requireMeta;
|
|
3071
|
+
const objects = storeFor(meta.repoId);
|
|
3072
|
+
const limit = Math.max(1, Math.min(input.limit ?? 20, 100));
|
|
3073
|
+
// Resolve the starting commit.
|
|
3074
|
+
const start = yield* resolveRevision(meta.defaultBranch, input.ref);
|
|
3075
|
+
// Commit-time-ordered walk (v1: recomputed from the start each
|
|
3076
|
+
// page; the cursor is the last emitted oid).
|
|
3077
|
+
const frontier = [];
|
|
3078
|
+
const visited = new Set();
|
|
3079
|
+
const items = [];
|
|
3080
|
+
let skipping = input.cursor !== undefined;
|
|
3081
|
+
let hasMore = false;
|
|
3082
|
+
const pushFrontier = Effect.fn(function* (oid) {
|
|
3083
|
+
if (visited.has(oid))
|
|
3084
|
+
return;
|
|
3085
|
+
visited.add(oid);
|
|
3086
|
+
const row = yield* sql.first(`SELECT commit_time FROM commits WHERE oid = ?`, oid);
|
|
3087
|
+
if (row !== undefined) {
|
|
3088
|
+
frontier.push({ oid, time: row.commit_time });
|
|
3089
|
+
}
|
|
3090
|
+
});
|
|
3091
|
+
// The start may be a tag — peel to a commit.
|
|
3092
|
+
const startMeta = yield* objects.getMeta(start);
|
|
3093
|
+
if (startMeta === undefined) {
|
|
3094
|
+
return yield* new RefNotFound({ ref: input.ref ?? "HEAD" });
|
|
3095
|
+
}
|
|
3096
|
+
const startCommit = startMeta.type === ObjectType.tag
|
|
3097
|
+
? yield* peelOid(meta.repoId, start).pipe(Effect.map((peeled) => peeled ?? start))
|
|
3098
|
+
: start;
|
|
3099
|
+
yield* pushFrontier(startCommit);
|
|
3100
|
+
while (frontier.length > 0) {
|
|
3101
|
+
// pop max commit_time
|
|
3102
|
+
let best = 0;
|
|
3103
|
+
for (let i = 1; i < frontier.length; i++) {
|
|
3104
|
+
if (frontier[i].time > frontier[best].time)
|
|
3105
|
+
best = i;
|
|
3106
|
+
}
|
|
3107
|
+
const [next] = frontier.splice(best, 1);
|
|
3108
|
+
const oid = next.oid;
|
|
3109
|
+
const parents = yield* sql.all(`SELECT parent, ord FROM commit_parents WHERE oid = ? ORDER BY ord`, oid);
|
|
3110
|
+
for (const parent of parents) {
|
|
3111
|
+
yield* pushFrontier(parent.parent);
|
|
3112
|
+
}
|
|
3113
|
+
if (skipping) {
|
|
3114
|
+
if (oid === input.cursor)
|
|
3115
|
+
skipping = false;
|
|
3116
|
+
continue;
|
|
3117
|
+
}
|
|
3118
|
+
if (items.length >= limit) {
|
|
3119
|
+
hasMore = true;
|
|
3120
|
+
break;
|
|
3121
|
+
}
|
|
3122
|
+
const content = yield* objects.readContent(oid);
|
|
3123
|
+
const parsed = yield* parseCommit(content).pipe(Effect.mapError((error) => new StoreError({ reason: error.reason })));
|
|
3124
|
+
items.push({
|
|
3125
|
+
oid,
|
|
3126
|
+
tree: parsed.tree,
|
|
3127
|
+
parents: parsed.parents,
|
|
3128
|
+
author: {
|
|
3129
|
+
name: parsed.author.name,
|
|
3130
|
+
email: parsed.author.email,
|
|
3131
|
+
date: parsed.author.when,
|
|
3132
|
+
tz: parsed.author.tz,
|
|
3133
|
+
},
|
|
3134
|
+
committer: {
|
|
3135
|
+
name: parsed.committer.name,
|
|
3136
|
+
email: parsed.committer.email,
|
|
3137
|
+
date: parsed.committer.when,
|
|
3138
|
+
tz: parsed.committer.tz,
|
|
3139
|
+
},
|
|
3140
|
+
message: parsed.message,
|
|
3141
|
+
});
|
|
3142
|
+
}
|
|
3143
|
+
return {
|
|
3144
|
+
items,
|
|
3145
|
+
nextCursor: hasMore ? items[items.length - 1].oid : null,
|
|
3146
|
+
hasMore,
|
|
3147
|
+
};
|
|
3148
|
+
}),
|
|
3149
|
+
readCommitDiff: Effect.fn(function* (input) {
|
|
3150
|
+
const meta = yield* requireMeta;
|
|
3151
|
+
const objects = storeFor(meta.repoId);
|
|
3152
|
+
const readCommitOrFail = Effect.fn(function* (oid) {
|
|
3153
|
+
const objectMeta = yield* objects.getMeta(oid);
|
|
3154
|
+
if (objectMeta === undefined) {
|
|
3155
|
+
return yield* new ObjectNotFound({ oid });
|
|
3156
|
+
}
|
|
3157
|
+
if (objectMeta.type !== ObjectType.commit) {
|
|
3158
|
+
return yield* new WrongObjectType({
|
|
3159
|
+
oid,
|
|
3160
|
+
expected: "commit",
|
|
3161
|
+
actual: objectTypeName(objectMeta.type),
|
|
3162
|
+
});
|
|
3163
|
+
}
|
|
3164
|
+
const content = yield* objects.readContent(oid);
|
|
3165
|
+
return yield* parseCommit(content).pipe(Effect.mapError((error) => new StoreError({ reason: error.reason })));
|
|
3166
|
+
});
|
|
3167
|
+
const commit = yield* readCommitOrFail(input.oid);
|
|
3168
|
+
// First-parent diff (the GitHub default for merge commits).
|
|
3169
|
+
const parent = commit.parents[0] ?? null;
|
|
3170
|
+
const parentTree = parent === null
|
|
3171
|
+
? undefined
|
|
3172
|
+
: (yield* readCommitOrFail(parent)).tree;
|
|
3173
|
+
const result = yield* diffTrees(objects, parentTree, commit.tree);
|
|
3174
|
+
return {
|
|
3175
|
+
oid: input.oid,
|
|
3176
|
+
parent,
|
|
3177
|
+
files: result.files,
|
|
3178
|
+
truncated: result.truncated,
|
|
3179
|
+
};
|
|
3180
|
+
}),
|
|
3181
|
+
compareCommits: Effect.fn(function* (input) {
|
|
3182
|
+
const meta = yield* requireMeta;
|
|
3183
|
+
const objects = storeFor(meta.repoId);
|
|
3184
|
+
const baseOid = yield* resolveToCommit(meta.repoId, meta.defaultBranch, input.base);
|
|
3185
|
+
const headOid = yield* resolveToCommit(meta.repoId, meta.defaultBranch, input.head);
|
|
3186
|
+
// The classic merge-base paint walk over the commit-graph tables,
|
|
3187
|
+
// ordered by the pre-computed generation number (`gen`, maintained
|
|
3188
|
+
// at ingest): a common ancestor's gen is strictly less than any
|
|
3189
|
+
// node on a path to it, so processing gen-descending guarantees
|
|
3190
|
+
// the first both-flagged pop is a best common ancestor. Nodes
|
|
3191
|
+
// carrying both flags propagate both but are counted as neither.
|
|
3192
|
+
const BASE = 1;
|
|
3193
|
+
const HEAD = 2;
|
|
3194
|
+
const BOTH = 3;
|
|
3195
|
+
const flags = new Map();
|
|
3196
|
+
flags.set(baseOid, BASE);
|
|
3197
|
+
flags.set(headOid, (flags.get(headOid) ?? 0) | HEAD);
|
|
3198
|
+
const heap = [];
|
|
3199
|
+
const timeOf = new Map();
|
|
3200
|
+
const rowOf = (oid) => sql.first(`SELECT gen, commit_time FROM commits WHERE oid = ?`, oid);
|
|
3201
|
+
// seed (base === head short-circuits: mergeBase = both, 0/0)
|
|
3202
|
+
for (const oid of new Set([baseOid, headOid])) {
|
|
3203
|
+
const row = yield* rowOf(oid);
|
|
3204
|
+
if (row === undefined) {
|
|
3205
|
+
return yield* new ObjectNotFound({ oid });
|
|
3206
|
+
}
|
|
3207
|
+
heapPush(heap, { oid, gen: row.gen, time: row.commit_time });
|
|
3208
|
+
timeOf.set(oid, row.commit_time);
|
|
3209
|
+
}
|
|
3210
|
+
let mergeBase;
|
|
3211
|
+
let aheadBy = 0;
|
|
3212
|
+
let behindBy = 0;
|
|
3213
|
+
let pops = 0;
|
|
3214
|
+
const headSide = [];
|
|
3215
|
+
while (heap.length > 0 && pops < MAX_COMPARE_WALK) {
|
|
3216
|
+
// stop when nothing in the heap can still change the counts
|
|
3217
|
+
if (mergeBase !== undefined &&
|
|
3218
|
+
heap.every((n) => (flags.get(n.oid) & BOTH) === BOTH)) {
|
|
3219
|
+
break;
|
|
3220
|
+
}
|
|
3221
|
+
const node = heapPop(heap);
|
|
3222
|
+
pops++;
|
|
3223
|
+
const f = flags.get(node.oid);
|
|
3224
|
+
if ((f & BOTH) === BOTH) {
|
|
3225
|
+
if (mergeBase === undefined)
|
|
3226
|
+
mergeBase = node.oid;
|
|
3227
|
+
}
|
|
3228
|
+
else if (f === HEAD) {
|
|
3229
|
+
aheadBy++;
|
|
3230
|
+
headSide.push(node.oid);
|
|
3231
|
+
}
|
|
3232
|
+
else {
|
|
3233
|
+
behindBy++;
|
|
3234
|
+
}
|
|
3235
|
+
const parents = yield* sql.all(`SELECT parent FROM commit_parents WHERE oid = ? ORDER BY ord`, node.oid);
|
|
3236
|
+
for (const { parent } of parents) {
|
|
3237
|
+
const prev = flags.get(parent) ?? 0;
|
|
3238
|
+
const next = prev | f;
|
|
3239
|
+
if (next === prev)
|
|
3240
|
+
continue;
|
|
3241
|
+
flags.set(parent, next);
|
|
3242
|
+
if (prev === 0) {
|
|
3243
|
+
const row = yield* rowOf(parent);
|
|
3244
|
+
if (row === undefined)
|
|
3245
|
+
continue; // shallow boundary
|
|
3246
|
+
heapPush(heap, {
|
|
3247
|
+
oid: parent,
|
|
3248
|
+
gen: row.gen,
|
|
3249
|
+
time: row.commit_time,
|
|
3250
|
+
});
|
|
3251
|
+
timeOf.set(parent, row.commit_time);
|
|
3252
|
+
}
|
|
3253
|
+
// already-heaped nodes just get richer flags; no decrease-key
|
|
3254
|
+
// needed (flags only grow; both-flagged pops count as neither)
|
|
3255
|
+
}
|
|
3256
|
+
}
|
|
3257
|
+
if (mergeBase === undefined) {
|
|
3258
|
+
return yield* new NoMergeBase({
|
|
3259
|
+
base: asOid(baseOid),
|
|
3260
|
+
head: asOid(headOid),
|
|
3261
|
+
});
|
|
3262
|
+
}
|
|
3263
|
+
// head-side commits, committer-time descending, capped.
|
|
3264
|
+
headSide.sort((a, b) => (timeOf.get(b) ?? 0) - (timeOf.get(a) ?? 0));
|
|
3265
|
+
const commitOids = headSide.slice(0, MAX_COMPARE_COMMITS);
|
|
3266
|
+
const commits = [];
|
|
3267
|
+
for (const oid of commitOids) {
|
|
3268
|
+
const content = yield* objects.readContent(oid);
|
|
3269
|
+
const parsed = yield* parseCommit(content).pipe(Effect.mapError((error) => new StoreError({ reason: error.reason })));
|
|
3270
|
+
commits.push({
|
|
3271
|
+
oid,
|
|
3272
|
+
tree: parsed.tree,
|
|
3273
|
+
parents: parsed.parents,
|
|
3274
|
+
author: {
|
|
3275
|
+
name: parsed.author.name,
|
|
3276
|
+
email: parsed.author.email,
|
|
3277
|
+
date: parsed.author.when,
|
|
3278
|
+
tz: parsed.author.tz,
|
|
3279
|
+
},
|
|
3280
|
+
committer: {
|
|
3281
|
+
name: parsed.committer.name,
|
|
3282
|
+
email: parsed.committer.email,
|
|
3283
|
+
date: parsed.committer.when,
|
|
3284
|
+
tz: parsed.committer.tz,
|
|
3285
|
+
},
|
|
3286
|
+
message: parsed.message,
|
|
3287
|
+
});
|
|
3288
|
+
}
|
|
3289
|
+
// three-dot file diff: mergeBase tree vs head tree
|
|
3290
|
+
const treeOf = Effect.fn(function* (oid) {
|
|
3291
|
+
const row = yield* sql.first(`SELECT tree FROM commits WHERE oid = ?`, oid);
|
|
3292
|
+
if (row === undefined) {
|
|
3293
|
+
return yield* new StoreError({
|
|
3294
|
+
reason: `commit ${oid} missing from the commit graph`,
|
|
3295
|
+
});
|
|
3296
|
+
}
|
|
3297
|
+
return row.tree;
|
|
3298
|
+
});
|
|
3299
|
+
const mergeBaseTree = yield* treeOf(mergeBase);
|
|
3300
|
+
const headTree = yield* treeOf(headOid);
|
|
3301
|
+
const filesResult = yield* diffTrees(objects, mergeBaseTree, headTree);
|
|
3302
|
+
return {
|
|
3303
|
+
base: baseOid,
|
|
3304
|
+
head: headOid,
|
|
3305
|
+
mergeBase,
|
|
3306
|
+
aheadBy,
|
|
3307
|
+
behindBy,
|
|
3308
|
+
commits,
|
|
3309
|
+
commitsTruncated: headSide.length > MAX_COMPARE_COMMITS || pops >= MAX_COMPARE_WALK,
|
|
3310
|
+
files: filesResult.files,
|
|
3311
|
+
filesTruncated: filesResult.truncated,
|
|
3312
|
+
};
|
|
3313
|
+
}),
|
|
3314
|
+
readFileAtPath: Effect.fn(function* (input) {
|
|
3315
|
+
const meta = yield* requireMeta;
|
|
3316
|
+
const objects = storeFor(meta.repoId);
|
|
3317
|
+
const startOid = yield* resolveRevision(meta.defaultBranch, input.ref);
|
|
3318
|
+
// Resolve start → commit → root tree (peel tags on the way).
|
|
3319
|
+
const rootTree = yield* Effect.gen(function* () {
|
|
3320
|
+
let current = startOid;
|
|
3321
|
+
for (let hops = 0; hops < 16; hops++) {
|
|
3322
|
+
const objectMeta = yield* objects.getMeta(current);
|
|
3323
|
+
if (objectMeta === undefined) {
|
|
3324
|
+
return yield* new ObjectNotFound({ oid: current });
|
|
3325
|
+
}
|
|
3326
|
+
if (objectMeta.type === ObjectType.tree)
|
|
3327
|
+
return current;
|
|
3328
|
+
const content = yield* objects.readContent(current);
|
|
3329
|
+
if (objectMeta.type === ObjectType.commit) {
|
|
3330
|
+
const parsed = yield* parseCommit(content).pipe(Effect.mapError((error) => new StoreError({ reason: error.reason })));
|
|
3331
|
+
return parsed.tree;
|
|
3332
|
+
}
|
|
3333
|
+
if (objectMeta.type === ObjectType.tag) {
|
|
3334
|
+
const parsed = yield* parseTag(content).pipe(Effect.mapError((error) => new StoreError({ reason: error.reason })));
|
|
3335
|
+
current = parsed.object;
|
|
3336
|
+
continue;
|
|
3337
|
+
}
|
|
3338
|
+
return yield* new ObjectNotFound({ oid: current });
|
|
3339
|
+
}
|
|
3340
|
+
return yield* new ObjectNotFound({ oid: current });
|
|
3341
|
+
});
|
|
3342
|
+
const segments = input.path.split("/").filter(Boolean);
|
|
3343
|
+
if (segments.length === 0) {
|
|
3344
|
+
return yield* new ObjectNotFound({ oid: rootTree });
|
|
3345
|
+
}
|
|
3346
|
+
let treeOid = rootTree;
|
|
3347
|
+
for (let i = 0; i < segments.length; i++) {
|
|
3348
|
+
const content = yield* objects.readContent(treeOid);
|
|
3349
|
+
const entries = yield* parseTree(content).pipe(Effect.mapError((error) => new StoreError({ reason: error.reason })));
|
|
3350
|
+
const entry = entries.find((e) => e.name === segments[i]);
|
|
3351
|
+
if (entry === undefined) {
|
|
3352
|
+
return yield* new ObjectNotFound({ oid: `${input.path}` });
|
|
3353
|
+
}
|
|
3354
|
+
const kind = treeEntryKind(entry.mode);
|
|
3355
|
+
if (i === segments.length - 1) {
|
|
3356
|
+
if (kind !== "blob") {
|
|
3357
|
+
return yield* new ObjectNotFound({ oid: input.path });
|
|
3358
|
+
}
|
|
3359
|
+
const blobMeta = yield* objects.getMeta(entry.oid);
|
|
3360
|
+
if (blobMeta === undefined) {
|
|
3361
|
+
return yield* new ObjectNotFound({ oid: entry.oid });
|
|
3362
|
+
}
|
|
3363
|
+
const blob = yield* objects.readContent(entry.oid);
|
|
3364
|
+
return {
|
|
3365
|
+
oid: entry.oid,
|
|
3366
|
+
mode: entry.mode,
|
|
3367
|
+
size: blobMeta.size,
|
|
3368
|
+
content: blob,
|
|
3369
|
+
};
|
|
3370
|
+
}
|
|
3371
|
+
if (kind !== "tree") {
|
|
3372
|
+
return yield* new ObjectNotFound({ oid: input.path });
|
|
3373
|
+
}
|
|
3374
|
+
treeOid = entry.oid;
|
|
3375
|
+
}
|
|
3376
|
+
// unreachable — the loop returns or fails
|
|
3377
|
+
return yield* new ObjectNotFound({ oid: input.path });
|
|
3378
|
+
}),
|
|
3379
|
+
createPull: Effect.fn(function* (input) {
|
|
3380
|
+
yield* requireMeta;
|
|
3381
|
+
const baseRef = yield* normalizeBranchRef(input.base);
|
|
3382
|
+
const headRef = yield* normalizeBranchRef(input.head);
|
|
3383
|
+
if (baseRef === headRef) {
|
|
3384
|
+
return yield* new ValidationError({
|
|
3385
|
+
message: "base and head must be different branches",
|
|
3386
|
+
});
|
|
3387
|
+
}
|
|
3388
|
+
for (const ref of [baseRef, headRef]) {
|
|
3389
|
+
const row = yield* sql.first(`SELECT name, oid FROM refs WHERE name = ?`, ref);
|
|
3390
|
+
if (row === undefined) {
|
|
3391
|
+
return yield* new BranchMissing({ ref });
|
|
3392
|
+
}
|
|
3393
|
+
}
|
|
3394
|
+
const duplicate = yield* sql.first(`SELECT number FROM pulls WHERE state = 'open' AND base_ref = ? AND head_ref = ?`, baseRef, headRef);
|
|
3395
|
+
if (duplicate !== undefined) {
|
|
3396
|
+
return yield* new PullExists({ number: duplicate.number });
|
|
3397
|
+
}
|
|
3398
|
+
const now = Date.now();
|
|
3399
|
+
// Allocate the number and insert the row in ONE transaction —
|
|
3400
|
+
// the DO's input/output gates make the counter race-free.
|
|
3401
|
+
const number = yield* sql.transactionSync((raw) => {
|
|
3402
|
+
const seq = raw
|
|
3403
|
+
.exec(`SELECT value FROM config WHERE key = 'pull_seq'`)
|
|
3404
|
+
.toArray()[0];
|
|
3405
|
+
const next = (seq === undefined ? 0 : Number(seq.value)) + 1;
|
|
3406
|
+
raw.exec(`INSERT INTO config (key, value) VALUES ('pull_seq', ?)
|
|
3407
|
+
ON CONFLICT (key) DO UPDATE SET value = excluded.value`, String(next));
|
|
3408
|
+
raw.exec(`INSERT INTO pulls (number, title, body, base_ref, head_ref, state, created_at, updated_at)
|
|
3409
|
+
VALUES (?, ?, ?, ?, ?, 'open', ?, ?)`, next, input.title, input.body ?? null, baseRef, headRef, now, now);
|
|
3410
|
+
return next;
|
|
3411
|
+
});
|
|
3412
|
+
return {
|
|
3413
|
+
number,
|
|
3414
|
+
title: input.title,
|
|
3415
|
+
body: input.body ?? null,
|
|
3416
|
+
baseRef,
|
|
3417
|
+
headRef,
|
|
3418
|
+
state: "open",
|
|
3419
|
+
createdAt: now,
|
|
3420
|
+
updatedAt: now,
|
|
3421
|
+
mergedAt: null,
|
|
3422
|
+
mergeCommit: null,
|
|
3423
|
+
};
|
|
3424
|
+
}),
|
|
3425
|
+
listPulls: Effect.fn(function* (input) {
|
|
3426
|
+
yield* requireMeta;
|
|
3427
|
+
const state = input.state ?? "open";
|
|
3428
|
+
const limit = Math.max(1, Math.min(input.limit ?? 20, 100));
|
|
3429
|
+
const cursor = input.cursor === undefined ? undefined : Number(input.cursor);
|
|
3430
|
+
const where = [];
|
|
3431
|
+
const bindings = [];
|
|
3432
|
+
if (state !== "all") {
|
|
3433
|
+
where.push("state = ?");
|
|
3434
|
+
bindings.push(state);
|
|
3435
|
+
}
|
|
3436
|
+
if (cursor !== undefined && Number.isFinite(cursor)) {
|
|
3437
|
+
where.push("number < ?");
|
|
3438
|
+
bindings.push(cursor);
|
|
3439
|
+
}
|
|
3440
|
+
const rows = yield* sql.all(`SELECT * FROM pulls
|
|
3441
|
+
${where.length > 0 ? `WHERE ${where.join(" AND ")}` : ""}
|
|
3442
|
+
ORDER BY number DESC LIMIT ?`, ...bindings, limit + 1);
|
|
3443
|
+
const items = rows.slice(0, limit).map(rowToPull);
|
|
3444
|
+
const hasMore = rows.length > limit;
|
|
3445
|
+
return {
|
|
3446
|
+
items,
|
|
3447
|
+
nextCursor: hasMore
|
|
3448
|
+
? String(items[items.length - 1].number)
|
|
3449
|
+
: null,
|
|
3450
|
+
hasMore,
|
|
3451
|
+
};
|
|
3452
|
+
}),
|
|
3453
|
+
getPull: Effect.fn(function* (number) {
|
|
3454
|
+
const meta = yield* requireMeta;
|
|
3455
|
+
const row = yield* loadPull(number);
|
|
3456
|
+
const pull = rowToPull(row);
|
|
3457
|
+
const empty = {
|
|
3458
|
+
baseOid: null,
|
|
3459
|
+
headOid: null,
|
|
3460
|
+
mergeBase: null,
|
|
3461
|
+
aheadBy: null,
|
|
3462
|
+
behindBy: null,
|
|
3463
|
+
mergeable: null,
|
|
3464
|
+
mergeableReason: null,
|
|
3465
|
+
};
|
|
3466
|
+
// A merged PR's record is `mergeCommit` — live fields stay null.
|
|
3467
|
+
if (pull.state === "merged") {
|
|
3468
|
+
return { ...pull, ...empty };
|
|
3469
|
+
}
|
|
3470
|
+
const baseRow = yield* sql.first(`SELECT name, oid FROM refs WHERE name = ?`, row.base_ref);
|
|
3471
|
+
const headRow = yield* sql.first(`SELECT name, oid FROM refs WHERE name = ?`, row.head_ref);
|
|
3472
|
+
if (baseRow === undefined || headRow === undefined) {
|
|
3473
|
+
// A branch is gone: everything downstream is uncomputable.
|
|
3474
|
+
return {
|
|
3475
|
+
...pull,
|
|
3476
|
+
...empty,
|
|
3477
|
+
baseOid: baseRow?.oid ?? null,
|
|
3478
|
+
headOid: headRow?.oid ?? null,
|
|
3479
|
+
};
|
|
3480
|
+
}
|
|
3481
|
+
const baseTip = baseRow.oid;
|
|
3482
|
+
const headTip = headRow.oid;
|
|
3483
|
+
const cmp = yield* paintWalk(baseTip, headTip, MAX_PULL_WALK);
|
|
3484
|
+
if (cmp.saturated) {
|
|
3485
|
+
return {
|
|
3486
|
+
...pull,
|
|
3487
|
+
...empty,
|
|
3488
|
+
baseOid: baseTip,
|
|
3489
|
+
headOid: headTip,
|
|
3490
|
+
mergeableReason: "unknown",
|
|
3491
|
+
};
|
|
3492
|
+
}
|
|
3493
|
+
const live = {
|
|
3494
|
+
...pull,
|
|
3495
|
+
baseOid: baseTip,
|
|
3496
|
+
headOid: headTip,
|
|
3497
|
+
mergeBase: cmp.mergeBase ?? null,
|
|
3498
|
+
aheadBy: cmp.aheadBy,
|
|
3499
|
+
behindBy: cmp.behindBy,
|
|
3500
|
+
};
|
|
3501
|
+
if (cmp.mergeBase === undefined) {
|
|
3502
|
+
// Disjoint histories: our trivial-merge rules can never merge.
|
|
3503
|
+
return {
|
|
3504
|
+
...live,
|
|
3505
|
+
mergeable: false,
|
|
3506
|
+
mergeableReason: "conflict",
|
|
3507
|
+
};
|
|
3508
|
+
}
|
|
3509
|
+
if (cmp.mergeBase === headTip) {
|
|
3510
|
+
return {
|
|
3511
|
+
...live,
|
|
3512
|
+
mergeable: false,
|
|
3513
|
+
mergeableReason: "up-to-date",
|
|
3514
|
+
};
|
|
3515
|
+
}
|
|
3516
|
+
if (cmp.mergeBase === baseTip) {
|
|
3517
|
+
return {
|
|
3518
|
+
...live,
|
|
3519
|
+
mergeable: true,
|
|
3520
|
+
mergeableReason: "ff",
|
|
3521
|
+
};
|
|
3522
|
+
}
|
|
3523
|
+
// Trivial-merge dry run: diff intersection only, no tree building.
|
|
3524
|
+
const objects = storeFor(meta.repoId);
|
|
3525
|
+
const mbTree = yield* treeOfCommit(cmp.mergeBase);
|
|
3526
|
+
const baseChanges = yield* diffTrees(objects, mbTree, yield* treeOfCommit(baseTip));
|
|
3527
|
+
const headChanges = yield* diffTrees(objects, mbTree, yield* treeOfCommit(headTip));
|
|
3528
|
+
if (baseChanges.truncated || headChanges.truncated) {
|
|
3529
|
+
// Can't see every change — conservatively not mergeable.
|
|
3530
|
+
return {
|
|
3531
|
+
...live,
|
|
3532
|
+
mergeable: false,
|
|
3533
|
+
mergeableReason: "conflict",
|
|
3534
|
+
};
|
|
3535
|
+
}
|
|
3536
|
+
const conflicts = conflictingPaths(baseChanges.files, headChanges.files);
|
|
3537
|
+
return {
|
|
3538
|
+
...live,
|
|
3539
|
+
mergeable: conflicts.length === 0,
|
|
3540
|
+
mergeableReason: conflicts.length === 0 ? "merge-commit" : "conflict",
|
|
3541
|
+
};
|
|
3542
|
+
}),
|
|
3543
|
+
updatePull: Effect.fn(function* (input) {
|
|
3544
|
+
yield* requireMeta;
|
|
3545
|
+
const row = yield* loadPull(input.number);
|
|
3546
|
+
const current = pullStateOf(row.state);
|
|
3547
|
+
if (input.state !== undefined && current === "merged") {
|
|
3548
|
+
return yield* new PullStateConflict({
|
|
3549
|
+
number: input.number,
|
|
3550
|
+
state: "merged",
|
|
3551
|
+
});
|
|
3552
|
+
}
|
|
3553
|
+
const title = input.title ?? row.title;
|
|
3554
|
+
const body = input.body === undefined ? row.body : input.body;
|
|
3555
|
+
const state = input.state ?? current;
|
|
3556
|
+
yield* sql.run(`UPDATE pulls SET title = ?, body = ?, state = ?, updated_at = ? WHERE number = ?`, title, body, state, Date.now(), input.number);
|
|
3557
|
+
return rowToPull(yield* loadPull(input.number));
|
|
3558
|
+
}),
|
|
3559
|
+
mergePull: Effect.fn(function* (input) {
|
|
3560
|
+
const meta = yield* requireMeta;
|
|
3561
|
+
if (meta.readOnly) {
|
|
3562
|
+
return yield* new ReadOnlyRepo();
|
|
3563
|
+
}
|
|
3564
|
+
const row = yield* loadPull(input.number);
|
|
3565
|
+
const state = pullStateOf(row.state);
|
|
3566
|
+
if (state !== "open") {
|
|
3567
|
+
return yield* new PullStateConflict({
|
|
3568
|
+
number: input.number,
|
|
3569
|
+
state,
|
|
3570
|
+
});
|
|
3571
|
+
}
|
|
3572
|
+
// Both branches must exist — the ref CAS below must NEVER
|
|
3573
|
+
// (re)create a deleted base branch.
|
|
3574
|
+
const baseRow = yield* sql.first(`SELECT name, oid FROM refs WHERE name = ?`, row.base_ref);
|
|
3575
|
+
if (baseRow === undefined) {
|
|
3576
|
+
return yield* new BranchMissing({ ref: row.base_ref });
|
|
3577
|
+
}
|
|
3578
|
+
const headRow = yield* sql.first(`SELECT name, oid FROM refs WHERE name = ?`, row.head_ref);
|
|
3579
|
+
if (headRow === undefined) {
|
|
3580
|
+
return yield* new BranchMissing({ ref: row.head_ref });
|
|
3581
|
+
}
|
|
3582
|
+
const baseTip = baseRow.oid;
|
|
3583
|
+
if (input.expectedBaseOid !== undefined &&
|
|
3584
|
+
input.expectedBaseOid !== baseTip) {
|
|
3585
|
+
return yield* new RefConflict({
|
|
3586
|
+
ref: row.base_ref,
|
|
3587
|
+
currentOid: asOid(baseTip),
|
|
3588
|
+
});
|
|
3589
|
+
}
|
|
3590
|
+
const headTip = headRow.oid;
|
|
3591
|
+
if (input.expectedHeadOid !== undefined &&
|
|
3592
|
+
input.expectedHeadOid !== headTip) {
|
|
3593
|
+
return yield* new RefConflict({
|
|
3594
|
+
ref: row.head_ref,
|
|
3595
|
+
currentOid: asOid(headTip),
|
|
3596
|
+
});
|
|
3597
|
+
}
|
|
3598
|
+
const cmp = yield* paintWalk(baseTip, headTip, MAX_PULL_MERGE_WALK);
|
|
3599
|
+
if (cmp.mergeBase === headTip) {
|
|
3600
|
+
return yield* new NothingToMerge({ number: input.number });
|
|
3601
|
+
}
|
|
3602
|
+
const now = Date.now();
|
|
3603
|
+
// ── fast-forward: base is an ancestor of head ──────────────────
|
|
3604
|
+
if (cmp.mergeBase === baseTip) {
|
|
3605
|
+
// No new objects, no graph rows (all present from the push) —
|
|
3606
|
+
// one transaction re-checks the CAS, flips the ref, and stamps
|
|
3607
|
+
// the pulls row atomically.
|
|
3608
|
+
const pull = yield* sql.transactionSync((raw, rollback) => {
|
|
3609
|
+
const rows = raw
|
|
3610
|
+
.exec(`SELECT name, oid FROM refs WHERE name = ?`, row.base_ref)
|
|
3611
|
+
.toArray();
|
|
3612
|
+
const currentOid = rows.length > 0 ? rows[0].oid : null;
|
|
3613
|
+
if (currentOid !== baseTip) {
|
|
3614
|
+
rollback(new RefConflict({
|
|
3615
|
+
ref: row.base_ref,
|
|
3616
|
+
currentOid: currentOid === null ? null : asOid(currentOid),
|
|
3617
|
+
}));
|
|
3618
|
+
}
|
|
3619
|
+
raw.exec(`INSERT INTO refs (name, oid) VALUES (?, ?)
|
|
3620
|
+
ON CONFLICT (name) DO UPDATE SET oid = excluded.oid`, row.base_ref, headTip);
|
|
3621
|
+
raw.exec(`UPDATE pulls SET state = 'merged', merged_at = ?, merge_commit = ?, updated_at = ? WHERE number = ?`, now, headTip, now, input.number);
|
|
3622
|
+
const updated = raw
|
|
3623
|
+
.exec(`SELECT * FROM pulls WHERE number = ?`, input.number)
|
|
3624
|
+
.toArray()[0];
|
|
3625
|
+
return rowToPull(updated);
|
|
3626
|
+
});
|
|
3627
|
+
// The base moved: the head snapshot (which serves clones
|
|
3628
|
+
// without waking this object) must say so.
|
|
3629
|
+
yield* writeHeadSnapshot;
|
|
3630
|
+
return {
|
|
3631
|
+
method: "ff",
|
|
3632
|
+
oid: headTip,
|
|
3633
|
+
pull,
|
|
3634
|
+
};
|
|
3635
|
+
}
|
|
3636
|
+
// ── trivial three-way merge commit ─────────────────────────────
|
|
3637
|
+
if (cmp.mergeBase === undefined) {
|
|
3638
|
+
// Unrelated histories (or a saturated walk): conservative
|
|
3639
|
+
// conflict — the server never guesses.
|
|
3640
|
+
return yield* new MergeConflict({
|
|
3641
|
+
number: input.number,
|
|
3642
|
+
paths: [],
|
|
3643
|
+
});
|
|
3644
|
+
}
|
|
3645
|
+
const objects = storeFor(meta.repoId);
|
|
3646
|
+
const mbTree = yield* treeOfCommit(cmp.mergeBase);
|
|
3647
|
+
const baseTree = yield* treeOfCommit(baseTip);
|
|
3648
|
+
const baseChanges = yield* diffTrees(objects, mbTree, baseTree);
|
|
3649
|
+
const headChanges = yield* diffTrees(objects, mbTree, yield* treeOfCommit(headTip));
|
|
3650
|
+
if (baseChanges.truncated || headChanges.truncated) {
|
|
3651
|
+
// A truncated diff hides changes — conflict detection would be
|
|
3652
|
+
// unsound, so refuse conservatively.
|
|
3653
|
+
return yield* new MergeConflict({
|
|
3654
|
+
number: input.number,
|
|
3655
|
+
paths: [],
|
|
3656
|
+
});
|
|
3657
|
+
}
|
|
3658
|
+
const conflicts = conflictingPaths(baseChanges.files, headChanges.files);
|
|
3659
|
+
if (conflicts.length > 0) {
|
|
3660
|
+
return yield* new MergeConflict({
|
|
3661
|
+
number: input.number,
|
|
3662
|
+
paths: conflicts.slice(0, MAX_CONFLICT_PATHS),
|
|
3663
|
+
});
|
|
3664
|
+
}
|
|
3665
|
+
// Build the merged tree: head's mergeBase→head changes applied
|
|
3666
|
+
// onto the CURRENT base tree (disjoint by the check above).
|
|
3667
|
+
const applied = yield* applyTreeChanges(objects, baseTree, headChanges.files);
|
|
3668
|
+
const shortHead = row.head_ref.startsWith("refs/heads/")
|
|
3669
|
+
? row.head_ref.slice("refs/heads/".length)
|
|
3670
|
+
: row.head_ref;
|
|
3671
|
+
const message = input.message ??
|
|
3672
|
+
`Merge pull request #${input.number} from ${shortHead}\n`;
|
|
3673
|
+
const when = Math.floor(now / 1000);
|
|
3674
|
+
const identity = {
|
|
3675
|
+
name: "git-service",
|
|
3676
|
+
email: "git-service@localhost",
|
|
3677
|
+
when,
|
|
3678
|
+
tz: "+0000",
|
|
3679
|
+
};
|
|
3680
|
+
const commitContent = yield* encodeCommit({
|
|
3681
|
+
tree: applied.root,
|
|
3682
|
+
parents: [baseTip, headTip],
|
|
3683
|
+
author: identity,
|
|
3684
|
+
committer: identity,
|
|
3685
|
+
message,
|
|
3686
|
+
}).pipe(Effect.mapError((e) => new StoreError({ reason: e.reason })));
|
|
3687
|
+
const mergeOid = yield* hashObject(ObjectType.commit, commitContent);
|
|
3688
|
+
// Stage under a synthetic push id WITH a pushes staging row first,
|
|
3689
|
+
// so the staging-GC alarm reaps the objects if we crash (or the
|
|
3690
|
+
// CAS below loses) — the exact crash-safety story of a push.
|
|
3691
|
+
const pushId = `pr-${input.number}-${yield* ulid()}`;
|
|
3692
|
+
yield* sql.run(`INSERT INTO pushes (push_id, started_at, state) VALUES (?, ?, 'staging')`, pushId, now);
|
|
3693
|
+
const zlibToStore = (error) => new StoreError({ reason: error.reason });
|
|
3694
|
+
const staged = [];
|
|
3695
|
+
for (const tree of applied.newTrees) {
|
|
3696
|
+
staged.push({
|
|
3697
|
+
oid: tree.oid,
|
|
3698
|
+
type: ObjectType.tree,
|
|
3699
|
+
size: tree.content.length,
|
|
3700
|
+
zdata: yield* Zlib.deflate(tree.content).pipe(Effect.mapError(zlibToStore)),
|
|
3701
|
+
});
|
|
3702
|
+
}
|
|
3703
|
+
staged.push({
|
|
3704
|
+
oid: mergeOid,
|
|
3705
|
+
type: ObjectType.commit,
|
|
3706
|
+
size: commitContent.length,
|
|
3707
|
+
zdata: yield* Zlib.deflate(commitContent).pipe(Effect.mapError(zlibToStore)),
|
|
3708
|
+
});
|
|
3709
|
+
yield* objects.insertStagedBatch(pushId, staged);
|
|
3710
|
+
// Crash safety: arm the staging-GC alarm (like the push path) so
|
|
3711
|
+
// a lost CAS below — or a crash before finalize — cannot leak the
|
|
3712
|
+
// staged objects; a committed push's row is ignored by the GC.
|
|
3713
|
+
yield* upsertJob("gc", null);
|
|
3714
|
+
yield* armAlarmAt(Date.now() + STAGING_TTL_MS);
|
|
3715
|
+
const graph = yield* computeGraphRows([
|
|
3716
|
+
{
|
|
3717
|
+
oid: mergeOid,
|
|
3718
|
+
tree: applied.root,
|
|
3719
|
+
parents: [baseTip, headTip],
|
|
3720
|
+
commitTime: when,
|
|
3721
|
+
},
|
|
3722
|
+
]);
|
|
3723
|
+
const results = yield* finalizeRefTxn({
|
|
3724
|
+
commands: [
|
|
3725
|
+
{ oldOid: baseTip, newOid: mergeOid, ref: row.base_ref },
|
|
3726
|
+
],
|
|
3727
|
+
atomic: true,
|
|
3728
|
+
pushId,
|
|
3729
|
+
graph,
|
|
3730
|
+
// Atomic with the ref flip + staged-object promotion.
|
|
3731
|
+
onCommitted: (raw) => {
|
|
3732
|
+
raw.exec(`UPDATE pulls SET state = 'merged', merged_at = ?, merge_commit = ?, updated_at = ? WHERE number = ?`, now, mergeOid, now, input.number);
|
|
3733
|
+
},
|
|
3734
|
+
});
|
|
3735
|
+
const outcome = results[0];
|
|
3736
|
+
if (outcome === undefined || !outcome.ok) {
|
|
3737
|
+
// Base moved between the pre-check and the transaction. The
|
|
3738
|
+
// staged objects stay parked under `pushId` for the GC alarm.
|
|
3739
|
+
const current = yield* sql.first(`SELECT name, oid FROM refs WHERE name = ?`, row.base_ref);
|
|
3740
|
+
return yield* new RefConflict({
|
|
3741
|
+
ref: row.base_ref,
|
|
3742
|
+
currentOid: current === undefined ? null : asOid(current.oid),
|
|
3743
|
+
});
|
|
3744
|
+
}
|
|
3745
|
+
// Post-merge compaction check deliberately skipped: the merge
|
|
3746
|
+
// adds at most a handful of small trees + one commit (the push
|
|
3747
|
+
// path's thresholds cover accumulation).
|
|
3748
|
+
yield* writeHeadSnapshot;
|
|
3749
|
+
return {
|
|
3750
|
+
method: "merge-commit",
|
|
3751
|
+
oid: mergeOid,
|
|
3752
|
+
pull: rowToPull(yield* loadPull(input.number)),
|
|
3753
|
+
};
|
|
3754
|
+
}),
|
|
3755
|
+
snapshotRows: () => snapshotStream(sql),
|
|
3756
|
+
fetch: Effect.gen(function* () {
|
|
3757
|
+
const request = yield* HttpServerRequest.HttpServerRequest;
|
|
3758
|
+
const path = parseWirePath(request.url);
|
|
3759
|
+
if (path === undefined) {
|
|
3760
|
+
return HttpServerResponse.text("not found", { status: 404 });
|
|
3761
|
+
}
|
|
3762
|
+
const meta = yield* readMeta;
|
|
3763
|
+
if (meta === undefined) {
|
|
3764
|
+
return HttpServerResponse.text("repository not found", {
|
|
3765
|
+
status: 404,
|
|
3766
|
+
});
|
|
3767
|
+
}
|
|
3768
|
+
// Stale-cache fail-safe (DESIGN.md §2.1): this DO only answers
|
|
3769
|
+
// for its own owner/name.
|
|
3770
|
+
if (path.owner !== meta.owner || path.repo !== meta.name) {
|
|
3771
|
+
return HttpServerResponse.text("repository not found", {
|
|
3772
|
+
status: 404,
|
|
3773
|
+
});
|
|
3774
|
+
}
|
|
3775
|
+
if (meta.status !== "ready") {
|
|
3776
|
+
return wire503;
|
|
3777
|
+
}
|
|
3778
|
+
if (path.endpoint === "info/refs" && request.method === "GET") {
|
|
3779
|
+
return yield* handleInfoRefs(request, path.service, meta);
|
|
3780
|
+
}
|
|
3781
|
+
if (path.endpoint === "git-upload-pack" &&
|
|
3782
|
+
request.method === "POST") {
|
|
3783
|
+
return yield* handleUploadPack(request, meta);
|
|
3784
|
+
}
|
|
3785
|
+
return HttpServerResponse.text("not found", { status: 404 });
|
|
3786
|
+
}).pipe(Effect.catchTag("StoreError", (error) => Effect.as(Effect.logError("git wire: storage failure", error), HttpServerResponse.text("internal error", { status: 500 }))), Effect.catchTag("PackIngestError", (error) => Effect.succeed(HttpServerResponse.uint8Array(errPkt(error.reason), {
|
|
3787
|
+
status: 200,
|
|
3788
|
+
headers: noCache,
|
|
3789
|
+
})))),
|
|
3790
|
+
alarm: () => Effect.gen(function* () {
|
|
3791
|
+
const jobs = yield* sql.all(`SELECT * FROM jobs WHERE state = 'running'`);
|
|
3792
|
+
// `purge` runs FIRST and every job is individually isolated: a
|
|
3793
|
+
// job that keeps crashing must never starve the others. (It
|
|
3794
|
+
// did: a fork job dying on every alarm blocked the purge job
|
|
3795
|
+
// behind it forever, wedging the repo in `status: deleting`
|
|
3796
|
+
// and reserving its name.)
|
|
3797
|
+
const order = (kind) => kind === "purge" ? 0 : kind === "gc" ? 2 : 1;
|
|
3798
|
+
const ordered = [...jobs].sort((a, b) => order(a.kind) - order(b.kind));
|
|
3799
|
+
for (const job of ordered) {
|
|
3800
|
+
const isolated = Effect.gen(function* () {
|
|
3801
|
+
switch (job.kind) {
|
|
3802
|
+
case "purge": {
|
|
3803
|
+
const wiped = yield* runPurgeAlarm;
|
|
3804
|
+
return wiped; // storage is gone — stop the whole alarm
|
|
3805
|
+
}
|
|
3806
|
+
case "import":
|
|
3807
|
+
yield* runImportAlarm(job);
|
|
3808
|
+
return false;
|
|
3809
|
+
case "fork":
|
|
3810
|
+
yield* runForkAlarm(job);
|
|
3811
|
+
return false;
|
|
3812
|
+
case "gc":
|
|
3813
|
+
yield* runGcJob;
|
|
3814
|
+
return false;
|
|
3815
|
+
case "compact":
|
|
3816
|
+
yield* runCompactAlarm;
|
|
3817
|
+
return false;
|
|
3818
|
+
case "bundle":
|
|
3819
|
+
yield* runBundleAlarm;
|
|
3820
|
+
return false;
|
|
3821
|
+
default:
|
|
3822
|
+
yield* sql.run(`DELETE FROM jobs WHERE kind = ?`, job.kind);
|
|
3823
|
+
return false;
|
|
3824
|
+
}
|
|
3825
|
+
}).pipe(Effect.catchCause((cause) => Effect.as(Effect.logError(`repo alarm job '${job.kind}' failed`, cause), false)));
|
|
3826
|
+
if (yield* isolated)
|
|
3827
|
+
return;
|
|
3828
|
+
}
|
|
3829
|
+
}).pipe(Effect.catchCause((cause) => Effect.gen(function* () {
|
|
3830
|
+
yield* Effect.logError("repo alarm failed", cause);
|
|
3831
|
+
// Best-effort retry — never let the alarm defect.
|
|
3832
|
+
yield* armAlarmAt(Date.now() + 30_000).pipe(Effect.ignore);
|
|
3833
|
+
})), Effect.asVoid),
|
|
3834
|
+
};
|
|
3835
|
+
return shape;
|
|
3836
|
+
});
|
|
3837
|
+
}));
|
|
3838
|
+
export default GitRepoLive;
|
|
3839
|
+
//# sourceMappingURL=RepoObject.js.map
|