module Ecluse.Core.Registry.Npm.Publish (
publishRequest,
npmPublishDocument,
) where
import Data.Aeson (object, (.=))
import Data.Aeson qualified as Aeson
import Data.Aeson.Key qualified as Key
import Data.ByteArray.Encoding (Base (Base64), convertToBase)
import Data.ByteString qualified as BS
import Network.HTTP.Client (Request (method, requestBody, requestHeaders), RequestBody (RequestBodyBS))
import Network.HTTP.Types.Header (hAccept, hContentType)
import Ecluse.Core.Credential (Secret)
import Ecluse.Core.Package (PackageName, renderPackageName)
import Ecluse.Core.Registry (UrlFormationError)
import Ecluse.Core.Registry.Npm.Request (packageUrl, parseRequestEither, withToken)
import Ecluse.Core.Version (Version, renderVersion)
publishRequest ::
Text ->
Maybe Secret ->
PackageName ->
ByteString ->
Either UrlFormationError Request
publishRequest :: Text
-> Maybe Secret
-> PackageName
-> ByteString
-> Either UrlFormationError Request
publishRequest Text
baseUrl Maybe Secret
token PackageName
name ByteString
document = do
url <- Text -> PackageName -> Either UrlFormationError Text
packageUrl Text
baseUrl PackageName
name
base <- parseRequestEither url
pure
. withToken token
$ base
{ method = "PUT"
, requestBody = RequestBodyBS document
,
requestHeaders =
(hContentType, "application/json")
: (hAccept, "application/json")
: requestHeaders base
}
npmPublishDocument ::
PackageName ->
Version ->
Text ->
Maybe Text ->
Maybe Text ->
ByteString ->
ByteString
npmPublishDocument :: PackageName
-> Version
-> Text
-> Maybe Text
-> Maybe Text
-> ByteString
-> ByteString
npmPublishDocument PackageName
name Version
version Text
filename Maybe Text
integrity Maybe Text
shasum ByteString
tarball =
ByteString -> ByteString
forall l s. LazyStrict l s => l -> s
toStrict (ByteString -> ByteString)
-> (Value -> ByteString) -> Value -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Value -> ByteString
forall a. ToJSON a => a -> ByteString
Aeson.encode (Value -> ByteString) -> Value -> ByteString
forall a b. (a -> b) -> a -> b
$
[Pair] -> Value
object
[ Key
"_id" Key -> Text -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= Text
rendered
, Key
"name" Key -> Text -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= Text
rendered
, Key
"dist-tags" Key -> Value -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= [Pair] -> Value
object [Key
"latest" Key -> Text -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= Text
versionText]
, Key
"versions" Key -> Value -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= [Pair] -> Value
object [Text -> Key
Key.fromText Text
versionText Key -> Value -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= Value
manifest]
, Key
"_attachments" Key -> Value -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= [Pair] -> Value
object [Text -> Key
Key.fromText Text
filename Key -> Value -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= ByteString -> Value
attachmentObject ByteString
tarball]
]
where
versionText :: Text
versionText = Version -> Text
renderVersion Version
version
rendered :: Text
rendered = PackageName -> Text
renderPackageName PackageName
name
manifest :: Value
manifest = Text -> Text -> Value -> Value
versionManifestObject Text
rendered Text
versionText (Text -> Maybe Text -> Maybe Text -> Value
distObject Text
filename Maybe Text
integrity Maybe Text
shasum)
versionManifestObject :: Text -> Text -> Aeson.Value -> Aeson.Value
versionManifestObject :: Text -> Text -> Value -> Value
versionManifestObject Text
rendered Text
versionText Value
dist =
[Pair] -> Value
object
[ Key
"name" Key -> Text -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= Text
rendered
, Key
"version" Key -> Text -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= Text
versionText
, Key
"dist" Key -> Value -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= Value
dist
]
distObject :: Text -> Maybe Text -> Maybe Text -> Aeson.Value
distObject :: Text -> Maybe Text -> Maybe Text -> Value
distObject Text
filename Maybe Text
integrity Maybe Text
shasum =
[Pair] -> Value
object
( [Key
"tarball" Key -> Text -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= Text
filename]
[Pair] -> [Pair] -> [Pair]
forall a. Semigroup a => a -> a -> a
<> [Pair] -> (Text -> [Pair]) -> Maybe Text -> [Pair]
forall b a. b -> (a -> b) -> Maybe a -> b
maybe [] (\Text
i -> [Key
"integrity" Key -> Text -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= Text
i]) Maybe Text
integrity
[Pair] -> [Pair] -> [Pair]
forall a. Semigroup a => a -> a -> a
<> [Pair] -> (Text -> [Pair]) -> Maybe Text -> [Pair]
forall b a. b -> (a -> b) -> Maybe a -> b
maybe [] (\Text
s -> [Key
"shasum" Key -> Text -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= Text
s]) Maybe Text
shasum
)
attachmentObject :: ByteString -> Aeson.Value
attachmentObject :: ByteString -> Value
attachmentObject ByteString
tarball =
[Pair] -> Value
object
[ Key
"content_type" Key -> Text -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= (Text
"application/octet-stream" :: Text)
, Key
"data" Key -> Text -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= Text
encodedTarball
, Key
"length" Key -> Int -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= ByteString -> Int
BS.length ByteString
tarball
]
where
encodedTarball :: Text
encodedTarball :: Text
encodedTarball = ByteString -> Text
forall a b. ConvertUtf8 a b => b -> a
decodeUtf8 (Base -> ByteString -> ByteString
forall bin bout.
(ByteArrayAccess bin, ByteArray bout) =>
Base -> bin -> bout
convertToBase Base
Base64 ByteString
tarball :: ByteString)