-- 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: -- -- 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: -- -- 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: -- -- 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: -- -- -- -- 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