-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/
-- | DSL for generating API boilerplate and docs
--
@package api-tools
@version 0.5.2
module Data.API.Doc.Subst
type Dict = Map String String
subst :: Dict -> String -> String
prep :: Dict -> [String] -> String
mkDict :: [(String, String)] -> Dict
extDict :: [(String, String)] -> Dict -> Dict
module Data.API.Utils
mkUTC :: UTCTime -> Value
mkUTC' :: UTCTime -> Text
mkUTC_ :: UTCTime -> String
parseUTC' :: Text -> Maybe UTCTime
parseUTC_ :: String -> Maybe UTCTime
-- | The "oh noes!" operator.
(?!) :: Maybe a -> e -> Either e a
(?!?) :: Either e a -> (e -> e') -> Either e' a
module Data.API.Types
-- | an API spec is made up of a list of type/element specs, each
-- specifying a Haskell type and JSON wrappers
type API = [Thing]
data Thing
ThComment :: MDComment -> Thing
ThNode :: APINode -> Thing
-- | Specifies an individual element/type of the API
data APINode
APINode :: TypeName -> MDComment -> Prefix -> Spec -> Conversion -> APINode
-- | name of Haskell type
anName :: APINode -> TypeName
-- | comment describing type in Markdown
anComment :: APINode -> MDComment
-- | distinct short prefix (see below)
anPrefix :: APINode -> Prefix
-- | the type specification
anSpec :: APINode -> Spec
-- | optional conversion functions
anConvert :: APINode -> Conversion
-- | TypeName must contain a valid Haskell type constructor
newtype TypeName
TypeName :: String -> TypeName
_TypeName :: TypeName -> String
-- | FieldName identifies recod fields and union alternatives must contain
-- a valid identifier valid in Haskell and any API client wrappers (e.g.,
-- if Ruby wrappers are to be generated the names should easily map into
-- Ruby)
newtype FieldName
FieldName :: String -> FieldName
_FieldName :: FieldName -> String
-- | Markdown comments are represented by strings
type MDComment = String
-- | a distinct case-insensitive short prefix used to form unique record
-- field names and data constructors:
--
--
-- - must be a valid Haskell identifier
- must be unique within
-- the API
--
type Prefix = CI String
-- | type/element specs are either simple type isomorphisms of basic JSON
-- types, records, unions or enumerated types
data Spec
SpNewtype :: SpecNewtype -> Spec
SpRecord :: SpecRecord -> Spec
SpUnion :: SpecUnion -> Spec
SpEnum :: SpecEnum -> Spec
SpSynonym :: APIType -> Spec
-- | SpecNewtype elements are isomorphisms of string, inetgers or booleans
data SpecNewtype
SpecNewtype :: BasicType -> Maybe Filter -> SpecNewtype
snType :: SpecNewtype -> BasicType
snFilter :: SpecNewtype -> Maybe Filter
-- | SpecRecord is your classsic product type.
data SpecRecord
SpecRecord :: [(FieldName, FieldType)] -> SpecRecord
srFields :: SpecRecord -> [(FieldName, FieldType)]
-- | In addition to the type and comment, record fields may carry a flag
-- indicating that they are read-only, and may have a default value,
-- which must be of a compatible type.
data FieldType
FieldType :: APIType -> Bool -> Maybe DefaultValue -> MDComment -> FieldType
ftType :: FieldType -> APIType
ftReadOnly :: FieldType -> Bool
ftDefault :: FieldType -> Maybe DefaultValue
ftComment :: FieldType -> MDComment
-- | SpecUnion is your classsic union type
data SpecUnion
SpecUnion :: [(FieldName, (APIType, MDComment))] -> SpecUnion
suFields :: SpecUnion -> [(FieldName, (APIType, MDComment))]
-- | SpecEnum is your classic enumerated type
data SpecEnum
SpecEnum :: [(FieldName, MDComment)] -> SpecEnum
seAlts :: SpecEnum -> [(FieldName, MDComment)]
type Conversion = Maybe (FieldName, FieldName)
-- | Type is either a list, Maybe, a named element of the API or a basic
-- type
data APIType
-- | list elements are types
TyList :: APIType -> APIType
-- | Maybe elements are types
TyMaybe :: APIType -> APIType
-- | the referenced type must be defined by the API
TyName :: TypeName -> APIType
-- | a JSON string, int, bool etc.
TyBasic :: BasicType -> APIType
-- | a generic JSON value
TyJSON :: APIType
-- | A default value for a field
data DefaultValue
DefValList :: DefaultValue
DefValMaybe :: DefaultValue
DefValString :: Text -> DefaultValue
DefValBool :: Bool -> DefaultValue
DefValInt :: Int -> DefaultValue
DefValUtc :: UTCTime -> DefaultValue
-- | the basic JSON types (N.B., no floating point numbers, yet)
data BasicType
-- | a JSON UTF-8 string
BTstring :: BasicType
-- | a base-64-encoded byte string
BTbinary :: BasicType
-- | a JSON bool
BTbool :: BasicType
-- | a JSON integral number
BTint :: BasicType
-- | a JSON UTC string
BTutc :: BasicType
data Filter
FtrStrg :: RegEx -> Filter
FtrIntg :: IntRange -> Filter
FtrUTC :: UTCRange -> Filter
data IntRange
IntRange :: Maybe Int -> Maybe Int -> IntRange
ir_lo :: IntRange -> Maybe Int
ir_hi :: IntRange -> Maybe Int
data UTCRange
UTCRange :: Maybe UTCTime -> Maybe UTCTime -> UTCRange
ur_lo :: UTCRange -> Maybe UTCTime
ur_hi :: UTCRange -> Maybe UTCTime
data RegEx
RegEx :: Text -> Regex -> RegEx
re_text :: RegEx -> Text
re_regex :: RegEx -> Regex
-- | Binary data is represented in JSON format as a base64-encoded string
newtype Binary
Binary :: ByteString -> Binary
_Binary :: Binary -> ByteString
-- | Convert a default value to an Aeson Value. This differs from
-- toJSON as it will not round-trip with fromJSON: UTC
-- default values are turned into strings.
defaultValueAsJsValue :: DefaultValue -> Value
mkRegEx :: Text -> RegEx
inIntRange :: Int -> IntRange -> Bool
inUTCRange :: UTCTime -> UTCRange -> Bool
instance FromJSON s0 => FromJSON (CI s0)
instance ToJSON s0 => ToJSON (CI s0)
instance FromJSON BasicType
instance ToJSON BasicType
instance FromJSON UTCRange
instance ToJSON UTCRange
instance FromJSON IntRange
instance ToJSON IntRange
instance FromJSON Filter
instance ToJSON Filter
instance FromJSON SpecNewtype
instance ToJSON SpecNewtype
instance FromJSON FieldType
instance ToJSON FieldType
instance FromJSON SpecRecord
instance ToJSON SpecRecord
instance FromJSON SpecUnion
instance ToJSON SpecUnion
instance FromJSON SpecEnum
instance ToJSON SpecEnum
instance FromJSON DefaultValue
instance ToJSON DefaultValue
instance FromJSON APIType
instance ToJSON APIType
instance FromJSON Spec
instance ToJSON Spec
instance FromJSON FieldName
instance ToJSON FieldName
instance FromJSON TypeName
instance ToJSON TypeName
instance FromJSON APINode
instance ToJSON APINode
instance FromJSON Thing
instance ToJSON Thing
instance Eq TypeName
instance Ord TypeName
instance Show TypeName
instance IsString TypeName
instance Show FieldName
instance Eq FieldName
instance Ord FieldName
instance IsString FieldName
instance Eq IntRange
instance Show IntRange
instance Eq UTCRange
instance Show UTCRange
instance Show Filter
instance Show SpecEnum
instance Eq BasicType
instance Show BasicType
instance Eq APIType
instance Show APIType
instance Show SpecUnion
instance Show SpecNewtype
instance Eq DefaultValue
instance Show DefaultValue
instance Show FieldType
instance Show SpecRecord
instance Show Spec
instance Show APINode
instance Show Thing
instance Show Binary
instance Eq Binary
instance Ord Binary
instance NFData Binary
instance Arbitrary Binary
instance Arbitrary Text
instance FromJSON Binary
instance ToJSON Binary
instance Lift DefaultValue
instance IsString APIType
instance Lift RegEx
instance Show RegEx
instance Eq RegEx
instance FromJSON RegEx
instance ToJSON RegEx
instance Lift UTCRange
instance Lift IntRange
-- | This module defines a JSON parser, like Aeson's FromJSON, but
-- with more detailed error-reporting capabilities. In particular, it
-- reports errors in a structured format, and can report multiple
-- independent errors rather than stopping on the first one encountered.
module Data.API.JSON
-- | Represents an error that can be encountered while parsing
data JSONError
Expected :: Expected -> String -> Value -> JSONError
BadFormat :: FormatExpected -> String -> Text -> JSONError
MissingField :: JSONError
MissingAlt :: [String] -> JSONError
UnexpectedField :: JSONError
UnexpectedEnumVal :: [Text] -> Text -> JSONError
IntRangeError :: String -> Int -> IntRange -> JSONError
UTCRangeError :: String -> UTCTime -> UTCRange -> JSONError
RegexError :: String -> Text -> RegEx -> JSONError
SyntaxError :: String -> JSONError
-- | At present, we do not distinguish between errors and warnings
type JSONWarning = JSONError
-- | JSON type expected at a particular position, when a value of a
-- different type was encountered
data Expected
ExpArray :: Expected
ExpBool :: Expected
ExpInt :: Expected
ExpObject :: Expected
ExpString :: Expected
-- | Special format expected of a string
data FormatExpected
FmtBinary :: FormatExpected
FmtUTC :: FormatExpected
FmtOther :: FormatExpected
-- | A position inside a JSON value is a list of steps, ordered innermost
-- first (so going inside an object prepends a step).
type Position = [Step]
-- | Each step may be into a field of an object, or a specific element of
-- an array.
data Step
InField :: Text -> Step
InElem :: Int -> Step
-- | Human-readable presentation of a list of parse errors with their
-- positions
prettyJSONErrorPositions :: [(JSONError, Position)] -> String
-- | Human-readable description of a JSON parse error
prettyJSONError :: JSONError -> String
-- | Human-readable description of a single step in a position
prettyStep :: Step -> String
-- | Like Parser, but keeping track of locations within the JSON
-- structure and able to report multiple errors.
--
-- Careful! The Monad instance does not agree with the
-- Applicative instance in all circumstances, and you should use
-- the Applicative instance where possible. In particular:
--
--
-- - pf <*> ps returns errors from both
-- arguments
- pf `ap` ps returns errors from pf
-- only
--
data ParserWithErrs a
-- | Options to modify the behaviour of the JSON parser
data ParseFlags
-- | Use this as a basis for overriding individual fields of the
-- ParseFlags record, in case more flags are added in the future.
defaultParseFlags :: ParseFlags
-- | Run a parser with given flags, starting in the outermost location, and
-- returning warnings even if the parse was successful
runParserWithErrsTop :: ParseFlags -> ParserWithErrs a -> Either [(JSONError, Position)] (a, [(JSONWarning, Position)])
-- | Like FromJSON, but keeping track of multiple errors and their
-- positions. Moreover, this class is more liberal in accepting invalid
-- inputs:
--
--
-- - a string like "3" is accepted as an integer; and
-- - the integers 0 and 1 are accepted as
-- booleans.
--
class FromJSONWithErrs a where parseJSONWithErrs v = case fromJSON v of { Error e -> failWith $ SyntaxError e Success a -> pure a }
parseJSONWithErrs :: FromJSONWithErrs a => Value -> ParserWithErrs a
-- | Run the JSON parser on a value to produce a result or a list of errors
-- with their positions. This should not be used inside an implementation
-- of parseJSONWithErrs as it will not pass on the current
-- position.
fromJSONWithErrs :: FromJSONWithErrs a => Value -> Either [(JSONError, Position)] a
-- | Run the JSON parser on a value to produce a result or a list of errors
-- with their positions. This version allows the ParseFlags to be
-- specified.
fromJSONWithErrs' :: FromJSONWithErrs a => ParseFlags -> Value -> Either [(JSONError, Position)] a
-- | Run the JSON parser on a value to produce a result or a list of errors
-- with their positions. This version allows the ParseFlags to be
-- specified, and produces warnings even if the parse succeeded.
fromJSONWithErrs'' :: FromJSONWithErrs a => ParseFlags -> Value -> Either [(JSONError, Position)] (a, [(JSONWarning, Position)])
-- | Decode a ByteString and run the JSON parser
decodeWithErrs :: FromJSONWithErrs a => ByteString -> Either [(JSONError, Position)] a
-- | Decode a ByteString and run the JSON parser, allowing the
-- ParseFlags to be specified
decodeWithErrs' :: FromJSONWithErrs a => ParseFlags -> ByteString -> Either [(JSONError, Position)] a
-- | Suitable as an implementation of parseJSON that uses the
-- FromJSONWithErrs instance (provided said instance was not
-- defined using fromJSON!).
parseJSONDefault :: FromJSONWithErrs a => Value -> Parser a
withParseFlags :: (ParseFlags -> ParserWithErrs a) -> ParserWithErrs a
failWith :: JSONError -> ParserWithErrs a
expectedArray :: Value -> JSONError
expectedBool :: Value -> JSONError
expectedInt :: Value -> JSONError
expectedObject :: Value -> JSONError
expectedString :: Value -> JSONError
badFormat :: String -> Text -> JSONError
withInt :: String -> (Int -> ParserWithErrs a) -> Value -> ParserWithErrs a
withIntRange :: IntRange -> String -> (Int -> ParserWithErrs a) -> Value -> ParserWithErrs a
withBinary :: String -> (Binary -> ParserWithErrs a) -> Value -> ParserWithErrs a
withBool :: String -> (Bool -> ParserWithErrs a) -> Value -> ParserWithErrs a
withText :: String -> (Text -> ParserWithErrs a) -> Value -> ParserWithErrs a
withRegEx :: RegEx -> String -> (Text -> ParserWithErrs a) -> Value -> ParserWithErrs a
withUTC :: String -> (UTCTime -> ParserWithErrs a) -> Value -> ParserWithErrs a
withUTCRange :: UTCRange -> String -> (UTCTime -> ParserWithErrs a) -> Value -> ParserWithErrs a
withVersion :: String -> (Version -> ParserWithErrs a) -> Value -> ParserWithErrs a
-- | Look up the value of a field, treating missing fields as null
withField :: Text -> (Value -> ParserWithErrs a) -> Object -> ParserWithErrs a
-- | Look up the value of a field, which may be read-only or use a default
-- value (depending on the ParseFlags).
withDefaultField :: Bool -> Maybe Value -> Text -> (Value -> ParserWithErrs a) -> Object -> ParserWithErrs a
-- | Parse the value of a field, treating missing fields as null
(.:.) :: FromJSONWithErrs a => Object -> Text -> ParserWithErrs a
-- | Parse the value of a field, failing on missing fields
(.::) :: FromJSONWithErrs a => Object -> Text -> ParserWithErrs a
-- | Match an inhabitant of a disjoint union, which should be an object
-- with a single field, and call the continuation corresponding to the
-- field name.
withUnion :: [(Text, Value -> ParserWithErrs a)] -> Value -> ParserWithErrs a
instance SafeCopy Step
instance FromJSON Step
instance ToJSON Step
instance FromJSON FormatExpected
instance ToJSON FormatExpected
instance FromJSON Expected
instance ToJSON Expected
instance FromJSON JSONError
instance ToJSON JSONError
instance Eq Expected
instance Show Expected
instance Eq FormatExpected
instance Show FormatExpected
instance Eq JSONError
instance Show JSONError
instance Eq Step
instance Show Step
instance Functor ParserWithErrs
instance FromJSONWithErrs Version
instance FromJSONWithErrs UTCTime
instance FromJSONWithErrs Text
instance FromJSONWithErrs Binary
instance FromJSONWithErrs Bool
instance FromJSONWithErrs Integer
instance FromJSONWithErrs Int
instance FromJSONWithErrs a => FromJSONWithErrs [a]
instance FromJSONWithErrs a => FromJSONWithErrs (Maybe a)
instance FromJSONWithErrs ()
instance FromJSONWithErrs Value
instance Monad ParserWithErrs
instance Alternative ParserWithErrs
instance Applicative ParserWithErrs
-- | A cheap and cheerful pretty-printing library
module Data.API.PP
class PP t
pp :: PP t => t -> String
class PPLines t
ppLines :: PPLines t => t -> [String]
inFrontOf :: String -> [String] -> [String]
indent :: [String] -> [String]
instance PPLines Step
instance (PPLines s, PPLines t) => PPLines (s, t)
instance PPLines t => PPLines [t]
instance PP DefaultValue
instance PP BasicType
instance PP APIType
instance PP FieldName
instance PP TypeName
instance PPLines Value
instance PP Text
instance PP t => PP (Set t)
instance PP Version
instance PP [Char]
-- | This module defines a normalised representation of APIs, used for
-- comparing them in the migrations changelog, and to analyse
-- dependencies.
module Data.API.NormalForm
-- | The API type has too much extra info for us to be able to simply
-- compare them with (==). Our strategy is to strip out
-- ancillary information and normalise into a canonical form, and then we
-- can use a simple (==) compare.
--
-- Our normalised API discards most of the details of each type, keeping
-- just essential information about each type. We discard order of types
-- and fields, so we can use just associative maps.
type NormAPI = Map TypeName NormTypeDecl
-- | The normal or canonical form for a type declaration, an
-- APINode. Equality of the normal form indicates equivalence of
-- APIs.
--
-- We track all types.
data NormTypeDecl
NRecordType :: NormRecordType -> NormTypeDecl
NUnionType :: NormUnionType -> NormTypeDecl
NEnumType :: NormEnumType -> NormTypeDecl
NTypeSynonym :: APIType -> NormTypeDecl
NNewtype :: BasicType -> NormTypeDecl
-- | The canonical form of a record type is a map from fields to values...
type NormRecordType = Map FieldName APIType
-- | ...similarly a union is a map from fields to alternatives...
type NormUnionType = Map FieldName APIType
-- | ...and an enum is a set of values.
type NormEnumType = Set FieldName
-- | Compute the normal form of an API, discarding extraneous information.
apiNormalForm :: API -> NormAPI
-- | Compute the normal form of a single type declaration.
declNF :: Spec -> NormTypeDecl
-- | Find the set of type names used in an API
typeDeclsFreeVars :: NormAPI -> Set TypeName
-- | Find the set of type names used in a declaration
typeDeclFreeVars :: NormTypeDecl -> Set TypeName
-- | Find the set of type names used in an type
typeFreeVars :: APIType -> Set TypeName
-- | Check if a type is declared in the API
typeDeclaredInApi :: TypeName -> NormAPI -> Bool
-- | Check if a type is used anywhere in the API
typeUsedInApi :: TypeName -> NormAPI -> Bool
-- | Check if the first type's transitive dependencies include the second
-- type
typeUsedInTransitiveDep :: TypeName -> TypeName -> NormAPI -> Bool
-- | Compute the transitive dependencies of a set of types
transitiveDeps :: NormAPI -> Set TypeName -> Set TypeName
-- | Compute the set of types that depend (transitively) on the given types
transitiveReverseDeps :: NormAPI -> Set TypeName -> Set TypeName
-- | Test that all the types used in the API are declared. If not, return
-- the set of undeclared types.
apiInvariant :: NormAPI -> Either (Set TypeName) ()
-- | Test that all the types used in a type declaration are declared in the
-- API. If not, return the set of undeclared types.
declIsValid :: NormTypeDecl -> NormAPI -> Either (Set TypeName) ()
-- | Test that all the free type names in a type are declared in the API.
-- If not, return the set of undeclared types.
typeIsValid :: APIType -> NormAPI -> Either (Set TypeName) ()
-- | Substitute types for type names in a declaration
substTypeDecl :: (TypeName -> APIType) -> NormTypeDecl -> NormTypeDecl
-- | Substitute types for type names in a type
substType :: (TypeName -> APIType) -> APIType -> APIType
-- | Rename the first type to the second throughout the API
renameTypeUses :: TypeName -> TypeName -> NormAPI -> NormAPI
instance Eq NormTypeDecl
instance Show NormTypeDecl
instance PPLines NormTypeDecl
-- | This module deals with validating API changelogs and migrating JSON
-- data between different versions of a schema.
module Data.API.Changes
-- | Migrate a dataset from one version of an API schema to another. The
-- data must be described by a named type, the name of which is assumed
-- not to change.
--
-- The db, rec and fld types must be
-- enumerations of all the custom migration tags in the changelog, as
-- generated by generateMigrationKind.
migrateDataDump :: (Read db, Read rec, Read fld) => (API, Version) -> (API, VersionExtra) -> APIChangelog -> CustomMigrations db rec fld -> TypeName -> DataChecks -> Value -> Either MigrateFailure (Value, [MigrateWarning])
-- | Check that a changelog adequately describes how to migrate from one
-- version to another.
validateChanges :: (Read db, Read rec, Read fld) => (API, Version) -> (API, VersionExtra) -> APIChangelog -> CustomMigrations db rec fld -> TypeName -> DataChecks -> Either ValidateFailure [ValidateWarning]
-- | Check that a dataset matches an API, which is necessary for succesful
-- migration. The name of the dataset's type must be specified.
dataMatchesAPI :: TypeName -> API -> Value -> Either (ValueError, Position) ()
-- | When to validate the data against the schema (each level implies the
-- preceding levels):
data DataChecks
-- | Not at all
NoChecks :: DataChecks
-- | At start and end of the migration
CheckStartAndEnd :: DataChecks
-- | After custom migrations
CheckCustom :: DataChecks
-- | After every change
CheckAll :: DataChecks
-- | An API changelog, consisting of a list of versions with the changes
-- from one version to the next. The versions must be in descending order
-- (according to the Ord Version instance).
data APIChangelog
-- | The changes from the previous version up to this version.
ChangesUpTo :: VersionExtra -> [APIChange] -> APIChangelog -> APIChangelog
-- | The initial version
ChangesStart :: Version -> APIChangelog
type APIWithChangelog = (API, APIChangelog)
-- | A single change within a changelog
data APIChange
ChAddType :: TypeName -> NormTypeDecl -> APIChange
ChDeleteType :: TypeName -> APIChange
ChRenameType :: TypeName -> TypeName -> APIChange
ChAddField :: TypeName -> FieldName -> APIType -> (Maybe DefaultValue) -> APIChange
ChDeleteField :: TypeName -> FieldName -> APIChange
ChRenameField :: TypeName -> FieldName -> FieldName -> APIChange
ChChangeField :: TypeName -> FieldName -> APIType -> MigrationTag -> APIChange
ChAddUnionAlt :: TypeName -> FieldName -> APIType -> APIChange
ChDeleteUnionAlt :: TypeName -> FieldName -> APIChange
ChRenameUnionAlt :: TypeName -> FieldName -> FieldName -> APIChange
ChAddEnumVal :: TypeName -> FieldName -> APIChange
ChDeleteEnumVal :: TypeName -> FieldName -> APIChange
ChRenameEnumVal :: TypeName -> FieldName -> FieldName -> APIChange
ChCustomType :: TypeName -> MigrationTag -> APIChange
ChCustomAll :: MigrationTag -> APIChange
-- | Represents either a released version (with a version number) or the
-- version under development, which is newer than any release
data VersionExtra
Release :: Version -> VersionExtra
DevVersion :: VersionExtra
showVersionExtra :: VersionExtra -> String
-- | The earliest version in the changelog
changelogStartVersion :: APIChangelog -> Version
-- | The latest version in the changelog
changelogVersion :: APIChangelog -> VersionExtra
-- | Custom migrations used in the changelog must be implemented in
-- Haskell, and supplied in this record. There are three kinds:
--
--
-- - Whole-database migrations, which may arbitrarily change the API
-- schema and the data to match;
-- - Type migrations, which may change the schema of a single type;
-- and
-- - Single field migrations, which may change only the type of the
-- field (with the new type specified in the changelog).
--
--
-- For database and type migrations, if the schema is unchanged, the
-- corresponding function should return Nothing.
--
-- The db, ty and fld parameters should be
-- instantiated with the enumeration types generated by
-- generateMigrationKinds, which correspond to the exact set of
-- custom migration tags used in the changelog.
data CustomMigrations db ty fld
CustomMigrations :: (db -> Object -> Either ValueError Object) -> (db -> NormAPI -> Either ApplyFailure (Maybe NormAPI)) -> (ty -> Value -> Either ValueError Value) -> (ty -> NormTypeDecl -> Either ApplyFailure (Maybe NormTypeDecl)) -> (fld -> Value -> Either ValueError Value) -> CustomMigrations db ty fld
databaseMigration :: CustomMigrations db ty fld -> db -> Object -> Either ValueError Object
databaseMigrationSchema :: CustomMigrations db ty fld -> db -> NormAPI -> Either ApplyFailure (Maybe NormAPI)
typeMigration :: CustomMigrations db ty fld -> ty -> Value -> Either ValueError Value
typeMigrationSchema :: CustomMigrations db ty fld -> ty -> NormTypeDecl -> Either ApplyFailure (Maybe NormTypeDecl)
fieldMigration :: CustomMigrations db ty fld -> fld -> Value -> Either ValueError Value
-- | Lift a custom record migration to work on arbitrary values
mkRecordMigration :: (Object -> Either ValueError Object) -> (Value -> Either ValueError Value)
-- | Lift a schema change on record types to work on arbitrary type
-- declarations
mkRecordMigrationSchema :: TypeName -> (NormRecordType -> Either ApplyFailure (Maybe NormRecordType)) -> (NormTypeDecl -> Either ApplyFailure (Maybe NormTypeDecl))
-- | Use for databaseMigration, typeMigration or
-- fieldMigration to indicate that changes to the data are not
-- required
noDataChanges :: a -> Either ValueError a
-- | Use for databaseMigrationSchema or typeMigrationSchema
-- to indicate that the schema should not be changed
noSchemaChanges :: a -> Either ApplyFailure (Maybe a)
-- | Generate enumeration datatypes corresponding to the custom migrations
-- used in an API migration changelog.
generateMigrationKinds :: APIChangelog -> String -> String -> String -> Q [Dec]
-- | Within the changelog, custom migrations are represented as strings, so
-- we have less type-safety.
type MigrationTag = String
-- | The API type has too much extra info for us to be able to simply
-- compare them with (==). Our strategy is to strip out
-- ancillary information and normalise into a canonical form, and then we
-- can use a simple (==) compare.
--
-- Our normalised API discards most of the details of each type, keeping
-- just essential information about each type. We discard order of types
-- and fields, so we can use just associative maps.
type NormAPI = Map TypeName NormTypeDecl
-- | The normal or canonical form for a type declaration, an
-- APINode. Equality of the normal form indicates equivalence of
-- APIs.
--
-- We track all types.
data NormTypeDecl
NRecordType :: NormRecordType -> NormTypeDecl
NUnionType :: NormUnionType -> NormTypeDecl
NEnumType :: NormEnumType -> NormTypeDecl
NTypeSynonym :: APIType -> NormTypeDecl
NNewtype :: BasicType -> NormTypeDecl
-- | The canonical form of a record type is a map from fields to values...
type NormRecordType = Map FieldName APIType
-- | ...similarly a union is a map from fields to alternatives...
type NormUnionType = Map FieldName APIType
-- | ...and an enum is a set of values.
type NormEnumType = Set FieldName
-- | Compute the normal form of an API, discarding extraneous information.
apiNormalForm :: API -> NormAPI
-- | Compute the normal form of a single type declaration.
declNF :: Spec -> NormTypeDecl
data MigrateFailure
ValidateFailure :: ValidateFailure -> MigrateFailure
ValueError :: ValueError -> Position -> MigrateFailure
type MigrateWarning = ValidateWarning
-- | Errors that may be discovered when validating a changelog
data ValidateFailure
-- | the changelog must be in descending order of versions
ChangelogOutOfOrder :: VersionExtra -> VersionExtra -> ValidateFailure
vfLaterVersion :: ValidateFailure -> VersionExtra
vfEarlierVersion :: ValidateFailure -> VersionExtra
-- | forbid migrating from one version to an earlier version
CannotDowngrade :: VersionExtra -> VersionExtra -> ValidateFailure
vfFromVersion :: ValidateFailure -> VersionExtra
vfToVersion :: ValidateFailure -> VersionExtra
-- | an API uses types that are not declared
ApiInvalid :: VersionExtra -> Set TypeName -> ValidateFailure
vfInvalidVersion :: ValidateFailure -> VersionExtra
vfMissingDeclarations :: ValidateFailure -> Set TypeName
-- | changelog entry does not apply
ChangelogEntryInvalid :: [APITableChange] -> APIChange -> ApplyFailure -> ValidateFailure
vfSuccessfullyApplied :: ValidateFailure -> [APITableChange]
vfFailedToApply :: ValidateFailure -> APIChange
vfApplyFailure :: ValidateFailure -> ApplyFailure
-- | changelog is incomplete (ie all entries apply ok but result isn't the
-- target api)
ChangelogIncomplete :: VersionExtra -> VersionExtra -> Map TypeName (MergeResult NormTypeDecl NormTypeDecl) -> ValidateFailure
vfChangelogVersion :: ValidateFailure -> VersionExtra
vfTargetVersion :: ValidateFailure -> VersionExtra
vfDifferences :: ValidateFailure -> Map TypeName (MergeResult NormTypeDecl NormTypeDecl)
data ValidateWarning
-- | Errors that may occur applying a single API change
data ApplyFailure
-- | for adding or renaming type
TypeExists :: TypeName -> ApplyFailure
afExistingType :: ApplyFailure -> TypeName
-- | for deleting or renaming a type
TypeDoesNotExist :: TypeName -> ApplyFailure
afMissingType :: ApplyFailure -> TypeName
-- | e.g. it's not a record type
TypeWrongKind :: TypeName -> TypeKind -> ApplyFailure
afTypeName :: ApplyFailure -> TypeName
afExpectedKind :: ApplyFailure -> TypeKind
-- | cannot delete/modify types that are still used
TypeInUse :: TypeName -> ApplyFailure
afTypeName :: ApplyFailure -> TypeName
-- | type refers to a non-existent type
TypeMalformed :: APIType -> Set TypeName -> ApplyFailure
afType :: ApplyFailure -> APIType
afMissingTypes :: ApplyFailure -> Set TypeName
-- | decl refers to a non-existent type
DeclMalformed :: TypeName -> NormTypeDecl -> Set TypeName -> ApplyFailure
afTypeName :: ApplyFailure -> TypeName
afDecl :: ApplyFailure -> NormTypeDecl
afMissingTypes :: ApplyFailure -> Set TypeName
-- | for adding or renaming a field
FieldExists :: TypeName -> TypeKind -> FieldName -> ApplyFailure
afTypeName :: ApplyFailure -> TypeName
afTypeKind :: ApplyFailure -> TypeKind
afExistingField :: ApplyFailure -> FieldName
-- | for deleting or renaming a field
FieldDoesNotExist :: TypeName -> TypeKind -> FieldName -> ApplyFailure
afTypeName :: ApplyFailure -> TypeName
afTypeKind :: ApplyFailure -> TypeKind
afMissingField :: ApplyFailure -> FieldName
-- | for adding a field, must be a default value compatible with the type
FieldBadDefaultValue :: TypeName -> FieldName -> APIType -> DefaultValue -> ApplyFailure
afTypeName :: ApplyFailure -> TypeName
afFieldName :: ApplyFailure -> FieldName
afFieldType :: ApplyFailure -> APIType
afBadDefault :: ApplyFailure -> DefaultValue
-- | for adding a field to a table
DefaultMissing :: TypeName -> FieldName -> ApplyFailure
afTypeName :: ApplyFailure -> TypeName
afFieldName :: ApplyFailure -> FieldName
-- | custom error in tableChange
TableChangeError :: String -> ApplyFailure
afCustomMessage :: ApplyFailure -> String
data TypeKind
TKRecord :: TypeKind
TKUnion :: TypeKind
TKEnum :: TypeKind
TKNewtype :: TypeKind
TKTypeSynonym :: TypeKind
data MergeResult a b
OnlyInLeft :: a -> MergeResult a b
InBoth :: a -> b -> MergeResult a b
OnlyInRight :: b -> MergeResult a b
-- | Errors that can be discovered when migrating data values
data ValueError
-- | Data doesn't match schema
JSONError :: JSONError -> ValueError
-- | Error generated during custom migration
CustomMigrationError :: String -> Value -> ValueError
-- | An API change was invalid
InvalidAPI :: ApplyFailure -> ValueError
prettyMigrateFailure :: MigrateFailure -> String
prettyValidateFailure :: ValidateFailure -> String
prettyValueError :: ValueError -> String
prettyValueErrorPosition :: (ValueError, Position) -> String
instance Eq APIChange
instance Show APIChange
instance Eq DataChecks
instance Ord DataChecks
instance Eq VersionExtra
instance Ord VersionExtra
instance Show VersionExtra
instance Eq APIChangelog
instance Show APIChangelog
instance Eq UpdateTypePos
instance Show UpdateTypePos
instance Eq UpdateDeclPos
instance Show UpdateDeclPos
instance Eq APITableChange
instance Show APITableChange
instance Show ValidateWarning
instance Eq TypeKind
instance Show TypeKind
instance Eq ApplyFailure
instance Show ApplyFailure
instance Eq ValueError
instance Show ValueError
instance (Eq a, Eq b) => Eq (MergeResult a b)
instance (Show a, Show b) => Show (MergeResult a b)
instance Eq ValidateFailure
instance Show ValidateFailure
instance Eq MigrateFailure
instance Show MigrateFailure
instance PPLines ValueError
instance PPLines ApplyFailure
instance PPLines APITableChange
instance PPLines ValidateFailure
instance PPLines MigrateFailure
instance PPLines APIChange
instance PP TypeKind
instance PP VersionExtra
module Data.API.Doc
-- | Generate a web page documenting a Call
callHtml :: DocInfo -> Dict -> Call -> String
-- | Generate a web page documenting all the Calls in a web
-- application
dirHtml :: DocInfo -> Dict -> [Call] -> String
-- | Documents a single method call on a resource in a web application
data Call
Call :: HTTPMethod -> [String] -> String -> Bool -> [Header] -> Maybe (APIType, String) -> [Param] -> [View] -> [Sample] -> Call
-- | HTTP method being documented
call_http_method :: Call -> HTTPMethod
-- | Relative URL path of the resource
call_path :: Call -> [String]
-- | Free-form text description
call_description :: Call -> String
-- | Does the call require authentication?
call_auth_required :: Call -> Bool
-- | HTTP headers relevant to the call
call_headers :: Call -> [Header]
-- | Type and example of request body
call_body :: Call -> Maybe (APIType, String)
-- | Query parameters relevant to the call
call_params :: Call -> [Param]
-- | Available views of the result data
call_views :: Call -> [View]
-- | Example responses
call_samples :: Call -> [Sample]
-- | Documents a HTTP header that may be supplied to a Call
data Header
Header :: String -> String -> String -> APIType -> Bool -> Header
-- | Header name
header_name :: Header -> String
-- | Example value for header
header_expl :: Header -> String
-- | Free-form text description
header_desc :: Header -> String
-- | Type of data in header
header_type :: Header -> APIType
-- | Is including the header with the request mandatory?
header_required :: Header -> Bool
-- | Documents a URL query parameter that may be included with a
-- Call
data Param
Param :: String -> String -> String -> Either String APIType -> Bool -> Param
-- | Parameter name
param_name :: Param -> String
-- | Example value for parameter
param_expl :: Param -> String
-- | Free-form text description
param_desc :: Param -> String
-- | Type of data in the parameter
param_type :: Param -> Either String APIType
-- | Is including the parameter mandatory?
param_required :: Param -> Bool
-- | Documents a specific view of the result data available in a
-- Call
data View
View :: String -> APIType -> String -> [Param] -> View
-- | View name
view_id :: View -> String
-- | Type of result data returned
view_type :: View -> APIType
-- | Free-form text description
view_doc :: View -> String
-- | Query parameters that may be supplied for this view
view_params :: View -> [Param]
-- | Example response data from a Call
data Sample
Sample :: StatusCode -> Body APIType -> Maybe String -> Sample
-- | HTTP status code for this example response
sample_status :: Sample -> StatusCode
-- | Type of example response
sample_type :: Sample -> Body APIType
-- | Content of response, or Nothing for empty response
sample_response :: Sample -> Maybe String
-- | Type for Sample response body, parameterised by possible JSON
-- types
data Body t
-- | An empty response
EmptyBody :: Body t
-- | A JSON response of the given type
JSONBody :: t -> Body t
-- | A non-empty, non-JSON response
OtherBody :: String -> Body t
-- | Record of arguments that must be supplied to generate HTML
-- documentation for a Call
data DocInfo
DocInfo :: (HTTPMethod -> [String] -> URL) -> (TypeName -> URL) -> DocInfo
-- | URL for individual call documentation from the index
doc_info_call_url :: DocInfo -> HTTPMethod -> [String] -> URL
-- | URL for documentation of an API type
doc_info_type_url :: DocInfo -> TypeName -> URL
type URL = String
type HTTPMethod = String
type StatusCode = Int
renderAPIType :: DocInfo -> APIType -> String
renderBodyType :: DocInfo -> Body APIType -> String
mk_link :: URL -> String -> String
-- | This module generates Markdown-formatted documentation for an API,
-- like this:
--
--
-- ###Foo
--
-- a test defn
--
-- JSON Type : **union object** (Haskell prefix is 'foo')
--
-- | Alternative | Type | Comment
-- | ----------- | ------- | -----------
-- | _`Baz`_ | boolean | just a bool
-- | _`Qux`_ | integer | just an int
--
module Data.API.Markdown
-- | Create human-readable API documentation in Markdown format
markdown :: MarkdownMethods -> API -> MDComment
data MarkdownMethods
MDM :: (TypeName -> MDComment) -> (TypeName -> MDComment) -> (MDComment -> MDComment -> MDComment) -> (FieldName -> APIType -> Maybe DefaultValue) -> MarkdownMethods
mdmSummaryPostfix :: MarkdownMethods -> TypeName -> MDComment
mdmLink :: MarkdownMethods -> TypeName -> MDComment
mdmPp :: MarkdownMethods -> MDComment -> MDComment -> MDComment
mdmFieldDefault :: MarkdownMethods -> FieldName -> APIType -> Maybe DefaultValue
defaultMarkdownMethods :: MarkdownMethods
-- | Document a single API comment or node in Markdown format
thing :: MarkdownMethods -> Thing -> MDComment -> MDComment
module Data.API.Parse
parseAPI :: String -> (Int, Int) -> String -> API
parseAPIWithChangelog :: String -> (Int, Int) -> String -> APIWithChangelog
api :: QuasiQuoter
apiWithChangelog :: QuasiQuoter
module Data.API.Tools.Combinators
-- | A Tool a is something that can generate TH
-- declarations from a value of type a. Tools can be combined
-- using the Monoid instance.
data Tool a
type APITool = Tool API
type APINodeTool = Tool APINode
-- | Execute a tool to generate some TH declarations.
runTool :: Tool a -> ToolSettings -> a -> Q [Dec]
-- | Construct a tool that does not depend on any settings
simpleTool :: (a -> Q [Dec]) -> Tool a
-- | Construct a tool that may depend on the settings
mkTool :: (ToolSettings -> a -> Q [Dec]) -> Tool a
-- | Tool is a contravariant functor
contramapTool :: (a -> b) -> Tool b -> Tool a
-- | Make a tool that reads its argument to decide what to do
readTool :: (a -> Tool a) -> Tool a
-- | Apply a tool that acts on elements of a list to the entire list
subTools :: Tool a -> Tool [a]
-- | Apply a tool that acts on nodes to an entire API
apiNodeTool :: Tool APINode -> Tool API
-- | Apply a tool that acts on datatype nodes (i.e. those that are not
-- synonyms) to an entire API
apiDataTypeTool :: Tool APINode -> Tool API
-- | Create a tool that acts on nodes from its action on individual specs.
apiSpecTool :: Tool (APINode, SpecNewtype) -> Tool (APINode, SpecRecord) -> Tool (APINode, SpecUnion) -> Tool (APINode, SpecEnum) -> Tool (APINode, APIType) -> Tool APINode
-- | Settings to control the behaviour of API tools. This record may be
-- extended in the future, so you should construct a value by overriding
-- individual fields of defaultToolSettings.
data ToolSettings
-- | Generate a warning when an instance declaration is omitted because it
-- already exists
warnOnOmittedInstance :: ToolSettings -> Bool
-- | Rename the constructors of filtered newtypes and generate smart
-- constructors that enforce the invariants
newtypeSmartConstructors :: ToolSettings -> Bool
-- | Default settings designed to be overridden.
defaultToolSettings :: ToolSettings
instance Monoid (Tool a)
-- | This module defines some utilities for working with Template Haskell,
-- which may be useful for defining Tools, but should be
-- considered internal implementation details of this package.
module Data.API.TH
-- | Construct an idiomatic expression (an expression in an Applicative
-- context), i.e.
--
--
-- app ke [] = ke
-- app ke [e1,e2,...,en] = ke <$> e1 <*> e2 ... <*> en
--
applicativeE :: ExpQ -> [ExpQ] -> ExpQ
-- | Add an instance declaration for a class, if such an instance does not
-- already exist
optionalInstanceD :: ToolSettings -> Name -> [TypeQ] -> [DecQ] -> Q [Dec]
-- | Construct a TH function with a type signature
funSigD :: Name -> TypeQ -> [ClauseQ] -> Q [Dec]
-- | Construct a simple TH definition
simpleD :: Name -> ExpQ -> Q Dec
-- | Construct a simple TH definition with a type signature
simpleSigD :: Name -> TypeQ -> ExpQ -> Q [Dec]
module Data.API.Tools.Datatypes
-- | Tool to generate datatypes and type synonyms corresponding to an API
datatypesTool :: APITool
-- | Name of the type corresponding to the API node, e.g. JobId
type_nm :: APINode -> Name
-- | Name of the representation type corresponding to the API node, which
-- differs from the type_nm only if custom conversion functions
-- are specified. This is also the name of the sole constructor for
-- newtypes and records.
rep_type_nm :: APINode -> Name
-- | The type corresponding to an API node
nodeT :: APINode -> TypeQ
-- | The representation type corresponding to an API node
nodeRepT :: APINode -> TypeQ
-- | The constructor for a record API node
nodeConE :: APINode -> ExpQ
-- | The constructor for a newtype, which might be renamed
nodeNewtypeConE :: ToolSettings -> APINode -> SpecNewtype -> ExpQ
-- | A record field in an API node, as an expression
nodeFieldE :: APINode -> FieldName -> ExpQ
-- | A prefixed constructor for a union or enum, as an expression
nodeAltConE :: APINode -> FieldName -> ExpQ
-- | A prefixed constructor for a union or enum, as a pattern
nodeAltConP :: APINode -> FieldName -> [PatQ] -> PatQ
-- | The projection function from a newtype API node, as an epxression
newtypeProjectionE :: APINode -> ExpQ
module Data.API.Tools.DeepSeq
-- | Tool to generate NFData instances for generated types.
deepSeqTool :: APITool
-- | A tool to generate maps to and from Text values corresponding
-- to inhabitants of enumerated types
module Data.API.Tools.Enum
-- | Tool to generate the maps between enumerations and Text
-- strings named by text_enum_nm and map_enum_nm.
enumTool :: APITool
-- | For an enum type E, name a function _text_E :: E ->
-- Text that gives a string corresponding to the inhabitant
-- of the type. For example, we generate something like this:
--
--
-- _text_FrameRate :: FrameRate -> T.Text
-- _text_FrameRate fr =
-- case fr of
-- FRauto -> "auto"
-- FR10 -> "10"
-- FR15 -> "15"
-- FR23_97 -> "23.97"
-- FR24 -> "24"
-- FR25 -> "25"
-- FR29_97 -> "29.97"
-- FR30 -> "30"
-- FR60 -> "60"
--
text_enum_nm :: APINode -> Name
-- | For an enum type E, name a map from Text values to
-- inhabitants of the type, for example:
--
--
-- _map_FrameRate :: Map Text FrameRate
-- _map_FrameRate = genTextMap _text_FrameRate
--
map_enum_nm :: APINode -> Name
-- | Tool for generating documentation-friendly examples
module Data.API.Tools.Example
-- | The Example class is used to generate a documentation-friendly example
-- for each type in the model
class Example a where example = arbitrary
example :: Example a => Gen a
-- | Tool to generate Example instances for types generated by
-- datatypesTool. This depends on quickCheckTool.
exampleTool :: APITool
-- | Generate a list of (type name, sample generator) pairs corresponding
-- to each type in the API, with samples encoded as JSON. This depends on
-- the Example instances generated by exampleTool. It
-- generates something like this:
--
--
-- samples :: [(String, Gen Value)]
-- samples = [("Foo", fmap toJSON (example :: Gen Foo)), ... ]
--
samplesTool :: Name -> APITool
instance Example UTCTime
instance Example Value
instance Example Binary
instance Example Text
instance Example Bool
instance Example Int
instance Example a => Example [a]
instance Example a => Example (Maybe a)
module Data.API.Tools.JSON
-- | Tool to generate ToJSON and FromJSONWithErrs instances
-- for types generated by datatypesTool. This depends on
-- enumTool. For historical reasons this does not generate
-- FromJSON instances; you probably want to use jsonTool'
-- instead.
jsonTool :: APITool
-- | Tool to generate ToJSON, FromJSON and
-- FromJSONWithErrs instances for types generated by
-- datatypesTool. This depends on enumTool. Note that
-- generated FromJSON and FromJSONWithErrs instances will
-- always agree on the decoding of a value, but that the
-- FromJSONWithErrs instances for basic types are more liberal
-- than FromJSON.
jsonTool' :: APITool
-- | Tool to generate ToJSON instance for an API node
toJsonNodeTool :: APINodeTool
-- | Tool to generate FromJSON instance for an API node, which
-- relies on the FromJSONWithErrs instance.
fromJsonNodeTool :: APINodeTool
-- | Tool to generate FromJSONWithErrs instance for an API node
fromJsonWithErrsNodeTool :: APINodeTool
module Data.API.Tools.JSONTests
-- | Tool to generate a list of tests of type [(String,
-- Property)] with the given name. This depends on
-- jsonTool and quickCheckTool.
jsonTestsTool :: Name -> APITool
-- | QuickCheck property that a Value decodes to an expected
-- Haskell value, using fromJSONWithErrs
prop_decodesTo :: (Eq a, FromJSONWithErrs a) => Value -> a -> Bool
-- | QuickCheck property that a Value decodes to an expected
-- Haskell value, using fromJSONWithErrs' with the given
-- ParseFlags
prop_decodesTo' :: (Eq a, FromJSONWithErrs a) => ParseFlags -> Value -> a -> Bool
-- | QuickCheck property that Haskell values can be encoded with
-- toJSON and decoded with fromJSONWithErrs to get the
-- original value
prop_resultsMatchRoundtrip :: (Eq a, ToJSON a, FromJSONWithErrs a) => a -> Bool
module Data.API.Tools.Lens
-- | Tool to make lenses for fields in generated types.
lensTool :: APITool
binary :: Iso' Binary ByteString
module Data.API.Tools.QuickCheck
-- | Tool to generate Arbitrary instances for generated types.
quickCheckTool :: APITool
instance Arbitrary UTCTime
module Data.API.Tools.SafeCopy
-- | Tool to derive SafeCopy instances for generated types. At
-- present, this derives only base version instances.
safeCopyTool :: APITool
instance SafeCopy Binary
-- | This module provides an interface for generating TH declarations from
-- an API. To use it, splice in a call to generate followed
-- by one or more calls to generateAPITools, like so:
--
--
-- $(generate myAPI)
-- $(generateAPITools [enumTool, jsonTool', quickCheckTool] myAPI)
--
--
-- If you wish to override any of the instances generated by the tools,
-- you can do so by writing instance declarations after the call to
-- generate but before the call to generateAPITools.
module Data.API.Tools
-- | Generate the datatypes corresponding to an API.
generate :: API -> Q [Dec]
-- | Apply a list of tools to an API, generating TH declarations.
-- See the individual tool descriptions for details. Note that
-- generate must be called first, and some tools have
-- dependencies, which must be included in the same or a preceding call
-- to generateAPITools.
generateAPITools :: API -> [APITool] -> Q [Dec]
-- | Generate the datatypes corresponding to an API, allowing the
-- ToolSettings to be overriden.
generateWith :: ToolSettings -> API -> Q [Dec]
-- | Apply a list of tools to an API, generating TH declarations.
-- This form allows the ToolSettings to be overridden.
generateAPIToolsWith :: ToolSettings -> API -> [APITool] -> Q [Dec]
-- | Settings to control the behaviour of API tools. This record may be
-- extended in the future, so you should construct a value by overriding
-- individual fields of defaultToolSettings.
data ToolSettings
-- | Default settings designed to be overridden.
defaultToolSettings :: ToolSettings
-- | Generate a warning when an instance declaration is omitted because it
-- already exists
warnOnOmittedInstance :: ToolSettings -> Bool
-- | Rename the constructors of filtered newtypes and generate smart
-- constructors that enforce the invariants
newtypeSmartConstructors :: ToolSettings -> Bool
-- | Tool to generate the maps between enumerations and Text
-- strings named by text_enum_nm and map_enum_nm.
enumTool :: APITool
-- | Tool to generate Example instances for types generated by
-- datatypesTool. This depends on quickCheckTool.
exampleTool :: APITool
-- | Tool to generate NFData instances for generated types.
deepSeqTool :: APITool
-- | Tool to generate ToJSON and FromJSONWithErrs instances
-- for types generated by datatypesTool. This depends on
-- enumTool. For historical reasons this does not generate
-- FromJSON instances; you probably want to use jsonTool'
-- instead.
jsonTool :: APITool
-- | Tool to generate ToJSON, FromJSON and
-- FromJSONWithErrs instances for types generated by
-- datatypesTool. This depends on enumTool. Note that
-- generated FromJSON and FromJSONWithErrs instances will
-- always agree on the decoding of a value, but that the
-- FromJSONWithErrs instances for basic types are more liberal
-- than FromJSON.
jsonTool' :: APITool
-- | Tool to generate a list of tests of type [(String,
-- Property)] with the given name. This depends on
-- jsonTool and quickCheckTool.
jsonTestsTool :: Name -> APITool
-- | Tool to make lenses for fields in generated types.
lensTool :: APITool
-- | Tool to generate Arbitrary instances for generated types.
quickCheckTool :: APITool
-- | Tool to derive SafeCopy instances for generated types. At
-- present, this derives only base version instances.
safeCopyTool :: APITool
-- | Generate a list of (type name, sample generator) pairs corresponding
-- to each type in the API, with samples encoded as JSON. This depends on
-- the Example instances generated by exampleTool. It
-- generates something like this:
--
--
-- samples :: [(String, Gen Value)]
-- samples = [("Foo", fmap toJSON (example :: Gen Foo)), ... ]
--
samplesTool :: Name -> APITool
module Data.API.Tools.Traversal
-- | Build a traversal of the root type (first argument) that updates
-- values of the second type, e.g. traversalTool Root
-- Sub produces
--
--
-- traverseSubRoot :: Applicative f => (Sub -> f Sub) -> Root -> f Root
--
--
-- along with similar functions for all the types nested inside
-- Root that depend on Sub.
--
-- Note that types with custom representations will not have traversals
-- generated automatically: if required, these must be defined manually
-- in the same module as the call to traversalTool, otherwise the
-- generated code will lead to scope errors.
traversalTool :: TypeName -> TypeName -> APITool
module Data.API.Tutorial
-- | This module contains datatypes generated from the DSL description of
-- the api-tools API; they thus correspond to the types in
-- Data.API.Types.
module Data.API.API.Gen
newtype RegularExpression
RegularExpression :: Text -> RegularExpression
_RegularExpression :: RegularExpression -> Text
data IntRange
IntRange :: !(Maybe Int) -> !(Maybe Int) -> IntRange
_ir_lo :: IntRange -> !(Maybe Int)
_ir_hi :: IntRange -> !(Maybe Int)
data UTCRange
UTCRange :: !(Maybe UTCTime) -> !(Maybe UTCTime) -> UTCRange
_ur_lo :: UTCRange -> !(Maybe UTCTime)
_ur_hi :: UTCRange -> !(Maybe UTCTime)
data Filter
FT_string :: !RegularExpression -> Filter
FT_integer :: !IntRange -> Filter
FT_utc :: !UTCRange -> Filter
data Conversion
Conversion :: !Text -> !Text -> Conversion
_cv_injection :: Conversion -> !Text
_cv_projection :: Conversion -> !Text
newtype TypeRef
TypeRef :: Text -> TypeRef
_TypeRef :: TypeRef -> Text
data BasicType
BT_string :: BasicType
BT_binary :: BasicType
BT_boolean :: BasicType
BT_integer :: BasicType
BT_utc :: BasicType
data APIType
TY_list :: !APIType -> APIType
TY_maybe :: !APIType -> APIType
TY_ref :: !TypeRef -> APIType
TY_basic :: !BasicType -> APIType
TY_json :: !Int -> APIType
data SpecNewtype
SpecNewtype :: !BasicType -> !(Maybe Filter) -> SpecNewtype
_sn_type :: SpecNewtype -> !BasicType
_sn_filter :: SpecNewtype -> !(Maybe Filter)
data DefaultValue
DV_list :: !Int -> DefaultValue
DV_maybe :: !Int -> DefaultValue
DV_string :: !Text -> DefaultValue
DV_boolean :: !Bool -> DefaultValue
DV_integer :: !Int -> DefaultValue
DV_utc :: !UTCTime -> DefaultValue
data Field
Field :: !Text -> !APIType -> !Bool -> !(Maybe DefaultValue) -> !Text -> Field
_fd_name :: Field -> !Text
_fd_type :: Field -> !APIType
_fd_readonly :: Field -> !Bool
_fd_default :: Field -> !(Maybe DefaultValue)
_fd_comment :: Field -> !Text
data Spec
SP_newtype :: !SpecNewtype -> Spec
SP_record :: ![Field] -> Spec
SP_union :: ![Field] -> Spec
SP_enum :: ![Text] -> Spec
SP_synonym :: !APIType -> Spec
data APINode
APINode :: !Text -> !Text -> !Text -> !Spec -> !(Maybe Conversion) -> APINode
_an_name :: APINode -> !Text
_an_comment :: APINode -> !Text
_an_prefix :: APINode -> !Text
_an_spec :: APINode -> !Spec
_an_convert :: APINode -> !(Maybe Conversion)
type APISpec = [APINode]
apiAPISimpleTests :: [(String, Property)]
apiAPISamples :: [(String, Gen Value)]
typeRef :: Iso' TypeRef Text
fd_type :: Lens' Field APIType
fd_readonly :: Lens' Field Bool
fd_name :: Lens' Field Text
fd_default :: Lens' Field (Maybe DefaultValue)
fd_comment :: Lens' Field Text
cv_projection :: Lens' Conversion Text
cv_injection :: Lens' Conversion Text
ur_lo :: Lens' UTCRange (Maybe UTCTime)
ur_hi :: Lens' UTCRange (Maybe UTCTime)
ir_lo :: Lens' IntRange (Maybe Int)
ir_hi :: Lens' IntRange (Maybe Int)
regularExpression :: Iso' RegularExpression Text
sn_type :: Lens' SpecNewtype BasicType
sn_filter :: Lens' SpecNewtype (Maybe Filter)
an_spec :: Lens' APINode Spec
an_prefix :: Lens' APINode Text
an_name :: Lens' APINode Text
an_convert :: Lens' APINode (Maybe Conversion)
an_comment :: Lens' APINode Text
_map_BasicType :: Map Text BasicType
_text_BasicType :: BasicType -> Text
instance Example DefaultValue
instance Example BasicType
instance Example TypeRef
instance Example APIType
instance Example Field
instance Example Conversion
instance Example UTCRange
instance Example IntRange
instance Example RegularExpression
instance Example Filter
instance Example SpecNewtype
instance Example Spec
instance Example APINode
instance SafeCopy DefaultValue
instance SafeCopy BasicType
instance SafeCopy TypeRef
instance SafeCopy APIType
instance SafeCopy Field
instance SafeCopy Conversion
instance SafeCopy UTCRange
instance SafeCopy IntRange
instance SafeCopy RegularExpression
instance SafeCopy Filter
instance SafeCopy SpecNewtype
instance SafeCopy Spec
instance SafeCopy APINode
instance Arbitrary DefaultValue
instance Arbitrary BasicType
instance Arbitrary TypeRef
instance Arbitrary APIType
instance Arbitrary Field
instance Arbitrary Conversion
instance Arbitrary UTCRange
instance Arbitrary IntRange
instance Arbitrary RegularExpression
instance Arbitrary Filter
instance Arbitrary SpecNewtype
instance Arbitrary Spec
instance Arbitrary APINode
instance FromJSONWithErrs DefaultValue
instance FromJSON DefaultValue
instance ToJSON DefaultValue
instance FromJSONWithErrs BasicType
instance FromJSON BasicType
instance ToJSON BasicType
instance FromJSONWithErrs TypeRef
instance FromJSON TypeRef
instance ToJSON TypeRef
instance FromJSONWithErrs APIType
instance FromJSON APIType
instance ToJSON APIType
instance FromJSONWithErrs Field
instance FromJSON Field
instance ToJSON Field
instance FromJSONWithErrs Conversion
instance FromJSON Conversion
instance ToJSON Conversion
instance FromJSONWithErrs UTCRange
instance FromJSON UTCRange
instance ToJSON UTCRange
instance FromJSONWithErrs IntRange
instance FromJSON IntRange
instance ToJSON IntRange
instance FromJSONWithErrs RegularExpression
instance FromJSON RegularExpression
instance ToJSON RegularExpression
instance FromJSONWithErrs Filter
instance FromJSON Filter
instance ToJSON Filter
instance FromJSONWithErrs SpecNewtype
instance FromJSON SpecNewtype
instance ToJSON SpecNewtype
instance FromJSONWithErrs Spec
instance FromJSON Spec
instance ToJSON Spec
instance FromJSONWithErrs APINode
instance FromJSON APINode
instance ToJSON APINode
instance Typeable RegularExpression
instance Typeable IntRange
instance Typeable UTCRange
instance Typeable Filter
instance Typeable Conversion
instance Typeable TypeRef
instance Typeable BasicType
instance Typeable APIType
instance Typeable SpecNewtype
instance Typeable DefaultValue
instance Typeable Field
instance Typeable Spec
instance Typeable APINode
instance Show RegularExpression
instance Eq RegularExpression
instance Ord RegularExpression
instance IsString RegularExpression
instance Show IntRange
instance Eq IntRange
instance Show UTCRange
instance Eq UTCRange
instance Show Filter
instance Eq Filter
instance Show Conversion
instance Eq Conversion
instance Show TypeRef
instance Eq TypeRef
instance Ord TypeRef
instance IsString TypeRef
instance Show BasicType
instance Eq BasicType
instance Ord BasicType
instance Bounded BasicType
instance Enum BasicType
instance Show APIType
instance Eq APIType
instance Show SpecNewtype
instance Eq SpecNewtype
instance Show DefaultValue
instance Eq DefaultValue
instance Show Field
instance Eq Field
instance Show Spec
instance Eq Spec
instance Show APINode
instance Eq APINode
-- | This module converts an API specified with the DSL into a JSON-encoded
-- object so that it can be used in clients.
module Data.API.API
-- | API description of the api-tools API itself
apiAPI :: API
-- | Take an API spec and generate a JSON description of the API
extractAPI :: API -> Value
instance FromJSONWithErrs Thing