cachix-api 1.2 → 1.3
raw patch · 3 files changed
+104/−10 lines, 3 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
+ Cachix.API: [abortMultipartUpload] :: BinaryCacheAPI route -> route :- (Summary "Abort a multipart upload" :> (CachixAuth :> ("cache" :> (Capture "name" Text :> ("multipart-nar" :> (Capture "narUuid" UUID :> ("abort" :> (QueryParam' '[Required] "uploadId" Text :> Post '[JSON] NoContent))))))))
+ Cachix.API: [completeNarUpload] :: BinaryCacheAPI route -> route :- (Summary "Complete a multipart upload" :> (Description "Verify the etags for each part and create the narinfo" :> (CachixAuth :> ("cache" :> (Capture "name" Text :> ("multipart-nar" :> (Capture "narUuid" UUID :> ("complete" :> (QueryParam' '[Required] "uploadId" Text :> (ReqBody '[JSON] CompletedMultipartUpload :> Post '[JSON] NoContent))))))))))
+ Cachix.API: [createAndUploadNar] :: BinaryCacheAPI route -> route :- (Summary "Upload a NAR directly to the Cachix Server" :> (Description "This is a legacy API for older Cachix clients. Prefer 'createNar' instead." :> (CachixAuth :> ("cache" :> (Capture "name" Text :> ("nar" :> (QueryParam "compression" CompressionMethod :> (StreamBody NoFraming XNixNar (ConduitT () ByteStringStreaming (ResourceT IO) ()) :> Post '[JSON] NoContent))))))))
+ Cachix.API: [uploadNarPart] :: BinaryCacheAPI route -> route :- (Summary "Retrieve a presigned URL to upload a part of a multipart NAR" :> (CachixAuth :> ("cache" :> (Capture "name" Text :> ("multipart-nar" :> (Capture "narUuid" UUID :> (QueryParam' '[Required] "uploadId" Text :> (QueryParam' '[Required] "partNumber" Int :> (ReqBody '[JSON] SigningData :> Post '[JSON] UploadPartResponse)))))))))
+ Cachix.Types.MultipartUpload: CompletedMultipartUpload :: CompletedParts -> NarInfoCreate -> CompletedMultipartUpload
+ Cachix.Types.MultipartUpload: CompletedPart :: Int -> Text -> CompletedPart
+ Cachix.Types.MultipartUpload: CreateMultipartUploadResponse :: UUID -> Text -> CreateMultipartUploadResponse
+ Cachix.Types.MultipartUpload: SigningData :: Text -> SigningData
+ Cachix.Types.MultipartUpload: UploadPartResponse :: Text -> UploadPartResponse
+ Cachix.Types.MultipartUpload: [contentMD5] :: SigningData -> Text
+ Cachix.Types.MultipartUpload: [eTag] :: CompletedPart -> Text
+ Cachix.Types.MultipartUpload: [narId] :: CreateMultipartUploadResponse -> UUID
+ Cachix.Types.MultipartUpload: [narInfoCreate] :: CompletedMultipartUpload -> NarInfoCreate
+ Cachix.Types.MultipartUpload: [partNumber] :: CompletedPart -> Int
+ Cachix.Types.MultipartUpload: [parts] :: CompletedMultipartUpload -> CompletedParts
+ Cachix.Types.MultipartUpload: [uploadId] :: CreateMultipartUploadResponse -> Text
+ Cachix.Types.MultipartUpload: [uploadUrl] :: UploadPartResponse -> Text
+ Cachix.Types.MultipartUpload: data CompletedMultipartUpload
+ Cachix.Types.MultipartUpload: data CompletedPart
+ Cachix.Types.MultipartUpload: data CreateMultipartUploadResponse
+ Cachix.Types.MultipartUpload: data SigningData
+ Cachix.Types.MultipartUpload: instance Control.DeepSeq.NFData Cachix.Types.MultipartUpload.CompletedPart
+ Cachix.Types.MultipartUpload: instance Control.DeepSeq.NFData Cachix.Types.MultipartUpload.CreateMultipartUploadResponse
+ Cachix.Types.MultipartUpload: instance Control.DeepSeq.NFData Cachix.Types.MultipartUpload.SigningData
+ Cachix.Types.MultipartUpload: instance Control.DeepSeq.NFData Cachix.Types.MultipartUpload.UploadPartResponse
+ Cachix.Types.MultipartUpload: instance Data.Aeson.Types.FromJSON.FromJSON Cachix.Types.MultipartUpload.CompletedMultipartUpload
+ Cachix.Types.MultipartUpload: instance Data.Aeson.Types.FromJSON.FromJSON Cachix.Types.MultipartUpload.CompletedPart
+ Cachix.Types.MultipartUpload: instance Data.Aeson.Types.FromJSON.FromJSON Cachix.Types.MultipartUpload.CreateMultipartUploadResponse
+ Cachix.Types.MultipartUpload: instance Data.Aeson.Types.FromJSON.FromJSON Cachix.Types.MultipartUpload.SigningData
+ Cachix.Types.MultipartUpload: instance Data.Aeson.Types.FromJSON.FromJSON Cachix.Types.MultipartUpload.UploadPartResponse
+ Cachix.Types.MultipartUpload: instance Data.Aeson.Types.ToJSON.ToJSON Cachix.Types.MultipartUpload.CompletedMultipartUpload
+ Cachix.Types.MultipartUpload: instance Data.Aeson.Types.ToJSON.ToJSON Cachix.Types.MultipartUpload.CompletedPart
+ Cachix.Types.MultipartUpload: instance Data.Aeson.Types.ToJSON.ToJSON Cachix.Types.MultipartUpload.CreateMultipartUploadResponse
+ Cachix.Types.MultipartUpload: instance Data.Aeson.Types.ToJSON.ToJSON Cachix.Types.MultipartUpload.SigningData
+ Cachix.Types.MultipartUpload: instance Data.Aeson.Types.ToJSON.ToJSON Cachix.Types.MultipartUpload.UploadPartResponse
+ Cachix.Types.MultipartUpload: instance Data.Swagger.Internal.Schema.ToSchema Cachix.Types.MultipartUpload.CompletedMultipartUpload
+ Cachix.Types.MultipartUpload: instance Data.Swagger.Internal.Schema.ToSchema Cachix.Types.MultipartUpload.CompletedPart
+ Cachix.Types.MultipartUpload: instance Data.Swagger.Internal.Schema.ToSchema Cachix.Types.MultipartUpload.CreateMultipartUploadResponse
+ Cachix.Types.MultipartUpload: instance Data.Swagger.Internal.Schema.ToSchema Cachix.Types.MultipartUpload.SigningData
+ Cachix.Types.MultipartUpload: instance Data.Swagger.Internal.Schema.ToSchema Cachix.Types.MultipartUpload.UploadPartResponse
+ Cachix.Types.MultipartUpload: instance GHC.Generics.Generic Cachix.Types.MultipartUpload.CompletedMultipartUpload
+ Cachix.Types.MultipartUpload: instance GHC.Generics.Generic Cachix.Types.MultipartUpload.CompletedPart
+ Cachix.Types.MultipartUpload: instance GHC.Generics.Generic Cachix.Types.MultipartUpload.CreateMultipartUploadResponse
+ Cachix.Types.MultipartUpload: instance GHC.Generics.Generic Cachix.Types.MultipartUpload.SigningData
+ Cachix.Types.MultipartUpload: instance GHC.Generics.Generic Cachix.Types.MultipartUpload.UploadPartResponse
+ Cachix.Types.MultipartUpload: instance GHC.Show.Show Cachix.Types.MultipartUpload.CompletedMultipartUpload
+ Cachix.Types.MultipartUpload: instance GHC.Show.Show Cachix.Types.MultipartUpload.CompletedPart
+ Cachix.Types.MultipartUpload: instance GHC.Show.Show Cachix.Types.MultipartUpload.CreateMultipartUploadResponse
+ Cachix.Types.MultipartUpload: instance GHC.Show.Show Cachix.Types.MultipartUpload.SigningData
+ Cachix.Types.MultipartUpload: instance GHC.Show.Show Cachix.Types.MultipartUpload.UploadPartResponse
+ Cachix.Types.MultipartUpload: newtype UploadPartResponse
+ Cachix.Types.MultipartUpload: type CompletedParts = Maybe (NonEmpty CompletedPart)
- Cachix.API: BinaryCacheAPI :: (route :- (CachixAuth :> ("cache" :> (Capture "name" Text :> ("nix-cache-info" :> Get '[XNixCacheInfo, JSON] NixCacheInfo))))) -> (route :- (CachixAuth :> ("cache" :> (Capture "name" Text :> (Capture "narinfohash" NarInfoHash :> Get '[XNixNarInfo, JSON] (Headers '[Header "Cache-Control" Text] CachixNarInfo)))))) -> (route :- (CachixAuth :> ("cache" :> (Capture "name" Text :> (Capture "narinfohash" NarInfoHash :> Head))))) -> (route :- (CachixAuth :> ("cache" :> (Capture "name" Text :> ("nar" :> (Capture "nar" NarFileName :> StreamGet NoFraming XNixNar (ConduitT () ByteStringStreaming (ResourceT IO) ()))))))) -> (route :- (CachixAuth :> ("cache" :> (Capture "name" Text :> Get '[JSON] BinaryCache)))) -> (route :- (CachixAuth :> ("cache" :> (Capture "name" Text :> ("narinfo" :> (Summary "Given a list of store hashes, return a list of those that are missing" :> (ReqBody '[JSON] [Text] :> Post '[JSON] [Text]))))))) -> (route :- (CachixAuth :> ("cache" :> (Capture "name" Text :> ("narurl" :> (Capture "nar" NarFileName :> Get '[JSON] Text)))))) -> (route :- (CachixAuth :> ("cache" :> (Capture "name" Text :> (Capture "narinfohash" NarInfoHash :> (ReqBody '[JSON] NarInfoCreate :> Post '[JSON] NoContent)))))) -> (route :- (CachixAuth :> ("cache" :> (Capture "name" Text :> ("nar" :> (QueryParam "compression" CompressionMethod :> (StreamBody NoFraming XNixNar (ConduitT () ByteStringStreaming (ResourceT IO) ()) :> Post '[JSON] NoContent))))))) -> (route :- (CachixAuth :> ("cache" :> (Capture "name" Text :> ("serve" :> (Capture "storehash" Text :> (CaptureAll "filepath" Text :> (Summary "Serve a file from a given store path" :> Get '[XNixNar] (Headers '[Header "X-Content-Type-Options" Text, Header "Cache-Control" Text] LazyByteStringStreaming))))))))) -> (route :- (CachixAuth :> ("cache" :> (Capture "name" Text :> ("key" :> (ReqBody '[JSON] SigningKeyCreate :> Post '[JSON] NoContent)))))) -> BinaryCacheAPI route
+ Cachix.API: BinaryCacheAPI :: (route :- (CachixAuth :> ("cache" :> (Capture "name" Text :> ("nix-cache-info" :> Get '[XNixCacheInfo, JSON] NixCacheInfo))))) -> (route :- (CachixAuth :> ("cache" :> (Capture "name" Text :> (Capture "narinfohash" NarInfoHash :> Get '[XNixNarInfo, JSON] (Headers '[Header "Cache-Control" Text] CachixNarInfo)))))) -> (route :- (CachixAuth :> ("cache" :> (Capture "name" Text :> (Capture "narinfohash" NarInfoHash :> Head))))) -> (route :- (CachixAuth :> ("cache" :> (Capture "name" Text :> ("nar" :> (Capture "nar" NarFileName :> Get302 '[XNixNar] '[])))))) -> (route :- (CachixAuth :> ("cache" :> (Capture "name" Text :> Get '[JSON] BinaryCache)))) -> (route :- (CachixAuth :> ("cache" :> (Capture "name" Text :> ("narinfo" :> (Summary "Given a list of store hashes, return a list of those that are missing" :> (ReqBody '[JSON] [Text] :> Post '[JSON] [Text]))))))) -> (route :- (CachixAuth :> ("cache" :> (Capture "name" Text :> ("narurl" :> (Capture "nar" NarFileName :> Get '[JSON] Text)))))) -> (route :- (Summary "Upload a NAR directly to the Cachix Server" :> (Description "This is a legacy API for older Cachix clients. Prefer 'createNar' instead." :> (CachixAuth :> ("cache" :> (Capture "name" Text :> ("nar" :> (QueryParam "compression" CompressionMethod :> (StreamBody NoFraming XNixNar (ConduitT () ByteStringStreaming (ResourceT IO) ()) :> Post '[JSON] NoContent))))))))) -> (route :- (Summary "Create an empty NAR and initiate a multipart upload" :> (CachixAuth :> ("cache" :> (Capture "name" Text :> ("multipart-nar" :> (QueryParam "compression" CompressionMethod :> Post '[JSON] CreateMultipartUploadResponse))))))) -> (route :- (Summary "Retrieve a presigned URL to upload a part of a multipart NAR" :> (CachixAuth :> ("cache" :> (Capture "name" Text :> ("multipart-nar" :> (Capture "narUuid" UUID :> (QueryParam' '[Required] "uploadId" Text :> (QueryParam' '[Required] "partNumber" Int :> (ReqBody '[JSON] SigningData :> Post '[JSON] UploadPartResponse)))))))))) -> (route :- (Summary "Complete a multipart upload" :> (Description "Verify the etags for each part and create the narinfo" :> (CachixAuth :> ("cache" :> (Capture "name" Text :> ("multipart-nar" :> (Capture "narUuid" UUID :> ("complete" :> (QueryParam' '[Required] "uploadId" Text :> (ReqBody '[JSON] CompletedMultipartUpload :> Post '[JSON] NoContent))))))))))) -> (route :- (Summary "Abort a multipart upload" :> (CachixAuth :> ("cache" :> (Capture "name" Text :> ("multipart-nar" :> (Capture "narUuid" UUID :> ("abort" :> (QueryParam' '[Required] "uploadId" Text :> Post '[JSON] NoContent))))))))) -> (route :- (CachixAuth :> ("cache" :> (Capture "name" Text :> (Capture "narinfohash" NarInfoHash :> (ReqBody '[JSON] NarInfoCreate :> Post '[JSON] NoContent)))))) -> (route :- (CachixAuth :> ("cache" :> (Capture "name" Text :> ("serve" :> (Capture "storehash" Text :> (CaptureAll "filepath" Text :> (Summary "Serve a file from a given store path" :> Get '[XNixNar] (Headers '[Header "X-Content-Type-Options" Text, Header "Cache-Control" Text] LazyByteStringStreaming))))))))) -> (route :- (CachixAuth :> ("cache" :> (Capture "name" Text :> ("key" :> (ReqBody '[JSON] SigningKeyCreate :> Post '[JSON] NoContent)))))) -> BinaryCacheAPI route
- Cachix.API: [createNar] :: BinaryCacheAPI route -> route :- (CachixAuth :> ("cache" :> (Capture "name" Text :> ("nar" :> (QueryParam "compression" CompressionMethod :> (StreamBody NoFraming XNixNar (ConduitT () ByteStringStreaming (ResourceT IO) ()) :> Post '[JSON] NoContent))))))
+ Cachix.API: [createNar] :: BinaryCacheAPI route -> route :- (Summary "Create an empty NAR and initiate a multipart upload" :> (CachixAuth :> ("cache" :> (Capture "name" Text :> ("multipart-nar" :> (QueryParam "compression" CompressionMethod :> Post '[JSON] CreateMultipartUploadResponse))))))
- Cachix.API: [nar] :: BinaryCacheAPI route -> route :- (CachixAuth :> ("cache" :> (Capture "name" Text :> ("nar" :> (Capture "nar" NarFileName :> StreamGet NoFraming XNixNar (ConduitT () ByteStringStreaming (ResourceT IO) ()))))))
+ Cachix.API: [nar] :: BinaryCacheAPI route -> route :- (CachixAuth :> ("cache" :> (Capture "name" Text :> ("nar" :> (Capture "nar" NarFileName :> Get302 '[XNixNar] '[])))))
Files
- cachix-api.cabal +2/−1
- src/Cachix/API.hs +58/−9
- src/Cachix/Types/MultipartUpload.hs +44/−0
cachix-api.cabal view
@@ -1,6 +1,6 @@ cabal-version: 2.2 name: cachix-api-version: 1.2+version: 1.3 synopsis: Servant HTTP API specification for https://cachix.org homepage: https://github.com/cachix/cachix#readme bug-reports: https://github.com/cachix/cachix/issues@@ -52,6 +52,7 @@ Cachix.Types.DeployResponse Cachix.Types.DeployResponse.V1 Cachix.Types.DeployResponse.V2+ Cachix.Types.MultipartUpload Cachix.Types.NarFileName Cachix.Types.NarInfo Cachix.Types.NarInfoCreate
src/Cachix/API.hs view
@@ -12,16 +12,18 @@ import qualified Cachix.Types.BinaryCache as BinaryCache import qualified Cachix.Types.ByteStringStreaming as ByteStringStreaming import Cachix.Types.ContentTypes+import qualified Cachix.Types.MultipartUpload as Multipart import Cachix.Types.NarFileName (NarFileName (..)) import qualified Cachix.Types.NarInfo as NarInfo import qualified Cachix.Types.NarInfoCreate as NarInfoCreate import qualified Cachix.Types.NarInfoHash as NarInfoHash import qualified Cachix.Types.NixCacheInfo as NixCacheInfo-import Cachix.Types.Servant (Head)+import Cachix.Types.Servant (Get302, Head) import Cachix.Types.Session (Session) import qualified Cachix.Types.SigningKeyCreate as SigningKeyCreate import Control.Monad.Trans.Resource import Data.Conduit (ConduitT)+import Data.UUID (UUID) import Protolude import Servant.API hiding (BasicAuth) import Servant.API.Generic@@ -62,7 +64,7 @@ :> Capture "name" Text :> "nar" :> Capture "nar" NarFileName- :> StreamGet NoFraming XNixNar (ConduitT () ByteStringStreaming.ByteStringStreaming (ResourceT IO) ()),+ :> Get302 '[XNixNar] '[], -- cachix specific getCache :: route@@ -87,22 +89,69 @@ :> "narurl" :> Capture "nar" NarFileName :> Get '[JSON] Text,- createNarinfo ::+ createAndUploadNar :: route- :- CachixAuth+ :- Summary "Upload a NAR directly to the Cachix Server"+ :> Description "This is a legacy API for older Cachix clients. Prefer 'createNar' instead."+ :> CachixAuth :> "cache" :> Capture "name" Text- :> Capture "narinfohash" NarInfoHash.NarInfoHash- :> ReqBody '[JSON] NarInfoCreate.NarInfoCreate+ :> "nar"+ :> QueryParam "compression" BinaryCache.CompressionMethod+ :> StreamBody NoFraming XNixNar (ConduitT () ByteStringStreaming.ByteStringStreaming (ResourceT IO) ()) :> Post '[JSON] NoContent, createNar :: route- :- CachixAuth+ :- Summary "Create an empty NAR and initiate a multipart upload"+ :> CachixAuth :> "cache" :> Capture "name" Text- :> "nar"+ :> "multipart-nar" :> QueryParam "compression" BinaryCache.CompressionMethod- :> StreamBody NoFraming XNixNar (ConduitT () ByteStringStreaming.ByteStringStreaming (ResourceT IO) ())+ :> Post '[JSON] Multipart.CreateMultipartUploadResponse,+ uploadNarPart ::+ route+ :- Summary "Retrieve a presigned URL to upload a part of a multipart NAR"+ :> CachixAuth+ :> "cache"+ :> Capture "name" Text+ :> "multipart-nar"+ :> Capture "narUuid" UUID+ :> QueryParam' '[Required] "uploadId" Text+ :> QueryParam' '[Required] "partNumber" Int+ :> ReqBody '[JSON] Multipart.SigningData+ :> Post '[JSON] Multipart.UploadPartResponse,+ completeNarUpload ::+ route+ :- Summary "Complete a multipart upload"+ :> Description "Verify the etags for each part and create the narinfo"+ :> CachixAuth+ :> "cache"+ :> Capture "name" Text+ :> "multipart-nar"+ :> Capture "narUuid" UUID+ :> "complete"+ :> QueryParam' '[Required] "uploadId" Text+ :> ReqBody '[JSON] Multipart.CompletedMultipartUpload+ :> Post '[JSON] NoContent,+ abortMultipartUpload ::+ route+ :- Summary "Abort a multipart upload"+ :> CachixAuth+ :> "cache"+ :> Capture "name" Text+ :> "multipart-nar"+ :> Capture "narUuid" UUID+ :> "abort"+ :> QueryParam' '[Required] "uploadId" Text+ :> Post '[JSON] NoContent,+ createNarinfo ::+ route+ :- CachixAuth+ :> "cache"+ :> Capture "name" Text+ :> Capture "narinfohash" NarInfoHash.NarInfoHash+ :> ReqBody '[JSON] NarInfoCreate.NarInfoCreate :> Post '[JSON] NoContent, serveNarContent :: route
+ src/Cachix/Types/MultipartUpload.hs view
@@ -0,0 +1,44 @@+module Cachix.Types.MultipartUpload where++import Cachix.Types.NarInfoCreate (NarInfoCreate)+import Data.Aeson (FromJSON, ToJSON)+import Data.Swagger (ToSchema)+import Data.UUID (UUID)+import Protolude++data CreateMultipartUploadResponse = CreateMultipartUploadResponse+ { narId :: UUID,+ uploadId :: Text+ }+ deriving stock (Generic, Show)+ deriving anyclass (ToJSON, FromJSON, ToSchema, NFData)++-- | Any hashes or headers required to create the presigned URL.+data SigningData = SigningData+ { contentMD5 :: Text+ }+ deriving stock (Generic, Show)+ deriving anyclass (ToJSON, FromJSON, ToSchema, NFData)++newtype UploadPartResponse = UploadPartResponse {uploadUrl :: Text}+ deriving stock (Generic, Show)+ deriving anyclass (ToJSON, FromJSON, ToSchema, NFData)++data CompletedPart = CompletedPart+ { partNumber :: Int,+ -- | An opaque identifier for the uploaded part.+ eTag :: Text+ }+ deriving stock (Generic, Show)+ deriving anyclass (ToJSON, FromJSON, ToSchema, NFData)++type CompletedParts = Maybe (NonEmpty CompletedPart)++data CompletedMultipartUpload = CompletedMultipartUpload+ { -- | A list of 'CompletedPart`, sorted by the 'partNumber'.+ parts :: CompletedParts,+ -- | The narinfo to create after verifying the upload.+ narInfoCreate :: NarInfoCreate+ }+ deriving stock (Generic, Show)+ deriving anyclass (ToJSON, FromJSON, ToSchema)