yarn-lock-0.6.2: src/Yarn/Lock/Types.hs
{-# LANGUAGE DeriveFunctor, OverloadedStrings #-}
{-|
Module : Yarn.Lock.Types
Description : Types for yarn.lock files
Maintainer : Profpatsch
Stability : experimental
-}
module Yarn.Lock.Types where
import Protolude hiding (try)
import qualified Data.Text as T
import qualified Data.MultiKeyedMap as MKM
import qualified Data.List.NonEmpty as NE
-- | Yarn lockfile.
--
-- It is a multi-keyed map (each value can be referenced by multiple keys).
-- This is achieved by using an intermediate key @ik@.
--
-- Attention: Might be changed to a newtype in a future release.
type Lockfile = MKM.MKMap PackageKey Package
-- TODO newtype Lockfile = Lockfile (MKM.MKMap PackageKey Package)
-- | Proxy type for our MKMap intermediate key
lockfileIkProxy :: Proxy Int
lockfileIkProxy = Proxy
-- | Key that indexes package for a specific version.
data PackageKey = PackageKey
{ name :: PackageKeyName -- ^ package name
, npmVersionSpec :: Text
-- ^ tring that specifies the version of a package;
-- sometimes a npm semver, sometimes an arbitrary string
} deriving (Show, Eq, Ord)
-- | The name of a package. They can be scoped, see
-- | <https://docs.npmjs.com/misc/scope> for an explanation.
data PackageKeyName
= SimplePackageKey Text
-- ^ just a package name
| ScopedPackageKey Text Text
-- ^ a scope and a package name (e.g. @types/foobar)
deriving (Show, Eq, Ord)
-- | Try to parse a string into a package key name (scoped or not).
parsePackageKeyName :: Text -> Maybe PackageKeyName
parsePackageKeyName n = case T.stripPrefix "@" n of
Nothing -> Just $ SimplePackageKey n
Just sc -> case T.breakOn "/" sc of
(_, "") -> Nothing
(scope, pkg) -> Just $ ScopedPackageKey scope (T.drop 1 pkg)
-- | Something with a list of 'PackageKey's pointing to it.
data Keyed a = Keyed (NE.NonEmpty PackageKey) a
deriving (Show, Eq, Ord, Functor)
-- | The actual npm package with dependencies and a way to download.
data Package = Package
{ version :: Text -- ^ resolved, specific version
, remote :: Remote
, dependencies :: [PackageKey] -- ^ list of dependencies
, optionalDependencies :: [PackageKey] -- ^ list of optional dependencies
} deriving (Eq, Show)
-- | Information on where to download the package.
data Remote
= FileRemote
{ fileUrl :: Text -- ^ URL to a remote file
, fileSha1 :: Text -- ^ sha1 hash of the file (attached to the link)
}
| FileRemoteNoIntegrity
{ fileNoIntegrityUrl :: Text -- ^ URL to a remote file
}
| GitRemote
{ gitRepoUrl :: Text -- ^ valid git remote URL
, gitRev :: Text -- ^ git tree-ish (commit, branch, &c.)
}
-- this is a bit of an oddidity, but what isn’t
| FileLocal
{ fileLocalPath :: Text -- ^ (relative) path to file on the local machine
, fileLocalSha1 :: Text -- ^ sha1 hash of the file (attached to the link)
}
| FileLocalNoIntegrity
{ fileLocalNoIntegrityPath :: Text -- ^ (relative) path to file on the local machine
} deriving (Eq, Show)