Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions webapi-openapi/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,38 @@
# Revision history for webapi-openapi

## Unreleased

* The registry emits dhall-do-api's current names (`OperationId`,
`mkOperationId`, `WebApi.Contract hiding (OperationId)`) and an
`ErrorText` instance for every named error type.
* A modular layout, `openapi-model-generator --config FILE` (JSON; see
`WebApi.OpenAPI.Modular`): one package per API, split into public
sublibraries by consumer. `model-<m>` per module (from the document's
`x-zb` object), the contract as the main library (`App`, `Routes.<M>`,
`Contract`, `Contract.<M>`), and `registry` (`Registry.Instances.<M>`,
`Registry.Ops.<M>`, `Registry`). Hand-written stanzas are appended from the
config's `cabalExtra`; `gen/warnings.txt` lists what could not be typed.
* In the modular layout:
* component names resolve once to PascalCase Haskell names, avoiding what
the generated modules import;
* an untyped or property-less schema is `Opaque` (its JSON, crossing to
Dhall as text), never a crash;
* optional arrays are `Maybe`, and `ToJSON` leaves absent fields out
rather than sending `null` (an update touches only what it names);
* `NoFieldSelectors`, and positional pattern variables in `ToJSON`;
* a route with several captures gets a named path record (`<Op>PP`)
instead of webapi's tuple, which dhall-do's bridge has no instances for;
* header parameters are a record whose fields are the header names in
snake case, with a ToHeader that sends each under its wire name and
leaves an absent optional header out;
* of several media types, JSON is kept; of several 2xx responses, the
lowest; form and multipart bodies are left out with a warning until a
plan can carry a file;
* array request bodies of generated types get a whole-value
`OverrideType` (until dhall-do-api has one for `Vector`).
* The legacy single-module layout (the flags) is unchanged; a golden test
(`test/golden/ns-currency`) pins its output.

## 0.1.0.0 -- YYYY-mm-dd

* First version. Released on an unsuspecting world.
34 changes: 24 additions & 10 deletions webapi-openapi/openapi-model-generator/Main.hs
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,13 @@ import qualified Data.ByteString.Lazy as BL
import qualified Data.HashMap.Internal as HM
import Options.Applicative
( (<**>),
(<|>),
fullDesc,
header,
info,
help,
long,
metavar,
optional,
showDefault,
value,
Expand All @@ -22,6 +24,7 @@ import Options.Applicative
Parser )
import System.Exit (die)
import WebApi.OpenAPI (generateModels, NamingMap)
import WebApi.OpenAPI.Modular (generateModular)

data CliArgs
= CliArgs
Expand All @@ -32,8 +35,17 @@ data CliArgs
enumMode :: String
}

cliParser :: Parser CliArgs
-- | The modular layout from a generator config, or the single-module
-- legacy layout from flags.
data Cmd = Modular FilePath | Legacy CliArgs

cliParser :: Parser Cmd
cliParser =
(Modular <$> strOption (long "config" <> metavar "FILE" <> help "generator config (JSON): the modular layout"))
<|> (Legacy <$> legacyParser)

legacyParser :: Parser CliArgs
legacyParser =
CliArgs
<$> strOption (long "inputJsonFP")
<*> strOption (long "outDirBaseFp")
Expand All @@ -43,13 +55,17 @@ cliParser =

main :: IO ()
main = do
CliArgs {..} <- execParser opts
namingMap <- maybe (pure HM.empty) loadNamingMap namingMapFP
sumEnums <- case enumMode of
"text" -> pure False
"sum" -> pure True
other -> die ("--enumMode must be text or sum, not " <> other)
generateModels inputJsonFP outDirBaseFp reqFilePathPrefix namingMap sumEnums
cmd <- execParser opts
case cmd of
Modular fp ->
either (\e -> die (fp <> ": bad generator config: " <> e)) generateModular . A.eitherDecode =<< BL.readFile fp
Legacy CliArgs {..} -> do
namingMap <- maybe (pure HM.empty) loadNamingMap namingMapFP
sumEnums <- case enumMode of
"text" -> pure False
"sum" -> pure True
other -> die ("--enumMode must be text or sum, not " <> other)
generateModels inputJsonFP outDirBaseFp reqFilePathPrefix namingMap sumEnums
where opts =
info
(cliParser <**> helper)
Expand All @@ -61,5 +77,3 @@ main = do
loadNamingMap fp =
either (\e -> die (fp <> ": bad naming map: " <> e)) pure . A.eitherDecode
=<< BL.readFile fp


627 changes: 466 additions & 161 deletions webapi-openapi/src/WebApi/OpenAPI.hs

Large diffs are not rendered by default.

Loading
Loading