Skip to content

Commit

Permalink
[#114] Add examples
Browse files Browse the repository at this point in the history
  • Loading branch information
dcastro committed Aug 20, 2022
1 parent 8ec224d commit 6ae301a
Show file tree
Hide file tree
Showing 5 changed files with 141 additions and 16 deletions.
76 changes: 72 additions & 4 deletions docs/swagger.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
},
"EntryPath": {
"type": "string",
"example": "/accounts/sre/gmail",
"pattern": "(/[abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_]*)+"
},
"Directory": {
Expand All @@ -35,6 +36,41 @@
"entries",
"subdirs"
],
"example": {
"subdirs": {
"accounts": {
"subdirs": {
"sre": {
"subdirs": {},
"entries": [
{
"tags": [
"some-tag"
],
"masterField": null,
"path": "/accounts/sre/gmail",
"fields": {
"password": {
"contents": "some-password",
"visibility": "private",
"dateModified": "2016-07-22T00:00:00Z"
},
"username": {
"contents": "some-username",
"visibility": "public",
"dateModified": "2016-07-22T00:00:00Z"
}
},
"dateModified": "2016-07-22T00:00:00Z"
}
]
}
},
"entries": []
}
},
"entries": []
},
"properties": {
"subdirs": {
"type": "object",
Expand All @@ -57,6 +93,7 @@
},
"FieldName": {
"type": "string",
"example": "password",
"pattern": "[abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_;]*"
},
"Field": {
Expand All @@ -68,7 +105,8 @@
],
"properties": {
"contents": {
"type": "string"
"type": "string",
"example": "some-password"
},
"visibility": {
"$ref": "#/components/schemas/FieldVisibility"
Expand Down Expand Up @@ -101,6 +139,7 @@
},
"EntryTag": {
"type": "string",
"example": "some-tag",
"pattern": "[abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_;]*"
},
"NewField": {
Expand All @@ -111,7 +150,8 @@
],
"properties": {
"contents": {
"type": "string"
"type": "string",
"example": "some-password"
},
"visibility": {
"$ref": "#/components/schemas/FieldVisibility"
Expand All @@ -133,6 +173,26 @@
"fields",
"tags"
],
"example": {
"tags": [
"some-tag"
],
"masterField": null,
"path": "/accounts/sre/gmail",
"fields": {
"password": {
"contents": "some-password",
"visibility": "private",
"dateModified": "2016-07-22T00:00:00Z"
},
"username": {
"contents": "some-username",
"visibility": "public",
"dateModified": "2016-07-22T00:00:00Z"
}
},
"dateModified": "2016-07-22T00:00:00Z"
},
"properties": {
"tags": {
"items": {
Expand Down Expand Up @@ -206,7 +266,8 @@
"required": false,
"in": "query",
"schema": {
"format": "name:<direction>\ndate:<direction>\n<direction>=[asc, desc]\n"
"format": "name:<direction>\ndate:<direction>\n<direction>=[asc, desc]\n",
"example": "name:asc"
}
},
{
Expand Down Expand Up @@ -295,6 +356,7 @@
"in": "query",
"schema": {
"type": "string",
"example": "password",
"pattern": "[abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_;]*"
}
}
Expand All @@ -303,7 +365,8 @@
"content": {
"application/json;charset=utf-8": {
"schema": {
"type": "string"
"type": "string",
"example": "some-password"
}
}
}
Expand Down Expand Up @@ -518,6 +581,7 @@
"in": "query",
"schema": {
"type": "string",
"example": "password",
"pattern": "[abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_;]*"
}
}
Expand Down Expand Up @@ -562,6 +626,7 @@
"in": "query",
"schema": {
"type": "string",
"example": "some-tag",
"pattern": "[abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_;]*"
}
}
Expand Down Expand Up @@ -604,6 +669,7 @@
"in": "query",
"schema": {
"type": "string",
"example": "some-tag",
"pattern": "[abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_;]*"
}
}
Expand Down Expand Up @@ -648,6 +714,7 @@
"in": "query",
"schema": {
"type": "string",
"example": "password",
"pattern": "[abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_;]*"
}
}
Expand Down Expand Up @@ -692,6 +759,7 @@
"in": "query",
"schema": {
"type": "string",
"example": "password",
"pattern": "[abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_;]*"
}
}
Expand Down
1 change: 1 addition & 0 deletions lib/CLI/Types.hs
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,7 @@ instance ToParamSchema (Sort, Direction) where
toParamSchema _ =
mempty
& format ?~ sortDirectionFormat
& example ?~ "name:asc"
where
sortDirectionFormat = T.unlines
[ "name:<direction>"
Expand Down
9 changes: 7 additions & 2 deletions lib/Coffer/Directory.hs
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,15 @@ module Coffer.Directory

import Coffer.Path (PathSegment, entryPathParentDir, pathSegments)
import Control.Lens
import Data.Aeson (toJSON)
import Data.Aeson.Casing
import Data.Aeson.TH
import Data.HashMap.Strict (HashMap)
import Data.HashMap.Strict qualified as HashMap
import Data.Maybe qualified as Maybe
import Data.OpenApi
import Entry (Entry)
import Data.OpenApi.Lens qualified as Schema
import Entry (Entry, exampleEntry)
import Entry qualified as E
import GHC.Generics (Generic)

Expand All @@ -43,7 +45,10 @@ deriveToJSON (aesonPrefix camelCase) ''Directory
makeLensesWith abbreviatedFields 'Directory

instance ToSchema Directory where
declareNamedSchema = genericDeclareNamedSchema $ fromAesonOptions (aesonPrefix camelCase)
declareNamedSchema proxy =
genericDeclareNamedSchema (fromAesonOptions (aesonPrefix camelCase)) proxy <&> \schema ->
schema
& Schema.schema . example ?~ toJSON (insertEntry exampleEntry emptyDir)

emptyDir :: Directory
emptyDir = Directory mempty mempty
Expand Down
19 changes: 14 additions & 5 deletions lib/Coffer/Path.hs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ module Coffer.Path
, Path(..)
, mkPath
, EntryPath(..)
, exampleEntryPath
, mkEntryPath
, entryPathName
, entryPathParentDir
Expand All @@ -28,7 +29,7 @@ module Coffer.Path
import BackendName (BackendName, newBackendName)
import Control.Lens
import Control.Monad ((>=>))
import Data.Aeson (ToJSON, Value(String))
import Data.Aeson (ToJSON, Value(String), toJSON)
import Data.Aeson qualified as A
import Data.Data (Typeable)
import Data.Hashable (Hashable)
Expand Down Expand Up @@ -67,14 +68,13 @@ data DirectoryContents = DirectoryContents
makeLensesWith abbreviatedFields ''DirectoryContents

instance ToSchema PathSegment where
declareNamedSchema _ = pure $ NamedSchema (Just "PathSegment")
declareNamedSchema _ = pure $ NamedSchema (Just "PathSexxgment") $
mempty
& Schema.pattern ?~ pathSegmentPattern
& type_ ?~ OpenApiString
& Schema.example ?~ "accounts"
where
pathSegmentPattern = [int|s|
[#{pathSegmentAllowedCharacters}]
|]
pathSegmentPattern = "aaa"

mkPathSegment :: Text -> Either Text PathSegment
mkPathSegment segment
Expand Down Expand Up @@ -141,6 +141,14 @@ newtype EntryPath = EntryPath { unEntryPath :: NonEmpty PathSegment }
deriving stock (Show, Eq, Generic)
deriving anyclass (Hashable)

exampleEntryPath :: EntryPath
exampleEntryPath =
EntryPath $
UnsafeMkPathSegment "accounts" :|
[ UnsafeMkPathSegment "sre"
, UnsafeMkPathSegment "gmail"
]

instance A.ToJSON EntryPath where
toJSON = String . pretty

Expand All @@ -149,6 +157,7 @@ instance ToParamSchema EntryPath where
mempty
& Schema.pattern ?~ entryPathPattern
& type_ ?~ OpenApiString
& example ?~ toJSON exampleEntryPath
where
segmentPattern :: Pattern
segmentPattern = [int|s|
Expand Down
52 changes: 47 additions & 5 deletions lib/Entry.hs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ module Entry
, visibility
, contents
, Entry
, exampleEntry
, newEntry
, path
, masterField
Expand All @@ -30,8 +31,9 @@ module Entry
)
where

import Coffer.Path (EntryPath)
import Coffer.Path (EntryPath, exampleEntryPath)
import Control.Lens
import Data.Aeson (toJSON)
import Data.Aeson qualified as A
import Data.Aeson.Casing
import Data.Aeson.TH
Expand All @@ -44,10 +46,10 @@ import Data.Set (Set)
import Data.Set qualified as S
import Data.Text (Text)
import Data.Text qualified as T
import Data.Time (UTCTime)
import Data.Time (UTCTime(..), fromGregorian)
import Fmt (Buildable, build)
import GHC.Generics (Generic)
import Servant (FromHttpApiData, ToHttpApiData)
import Servant (FromHttpApiData, Proxy(..), ToHttpApiData)
import System.Console.ANSI (SGR(Reset), setSGRCode)
import System.Console.ANSI.Codes (csi)

Expand All @@ -63,6 +65,7 @@ instance ToParamSchema FieldName where
mempty
& Schema.pattern ?~ fieldNamePattern
& type_ ?~ OpenApiString
& example ?~ toJSON (UnsafeFieldName "password")
where
fieldNamePattern = "[" <> T.pack allowedCharSet <> "]*"

Expand Down Expand Up @@ -95,12 +98,16 @@ instance ToParamSchema EntryTag where
mempty
& Schema.pattern ?~ entryTagPattern
& type_ ?~ OpenApiString
& example ?~ toJSON exampleEntryTag
where
entryTagPattern = "[" <> T.pack allowedCharSet <> "]*"

newtype BadEntryTag = BadEntryTag { unBadEntryTag :: Text }
deriving newtype Buildable

exampleEntryTag :: EntryTag
exampleEntryTag = UnsafeEntryTag "some-tag"

newEntryTag :: Text -> Either BadEntryTag EntryTag
newEntryTag tag
| T.null tag =
Expand Down Expand Up @@ -139,9 +146,14 @@ instance A.FromJSON FieldVisibility where

newtype FieldContents = FieldContents { unFieldContents :: Text }
deriving stock (Show, Eq, Ord)
deriving newtype (Hashable, A.FromJSON, A.ToJSON, A.FromJSONKey, A.ToJSONKey, ToSchema)
deriving newtype (Hashable, A.FromJSON, A.ToJSON, A.FromJSONKey, A.ToJSONKey)
makeLensesFor [("unFieldContents", "fieldContents")] ''FieldContents

instance ToSchema FieldContents where
declareNamedSchema _ = pure $ NamedSchema Nothing $ mempty
& type_ ?~ OpenApiString
& example ?~ toJSON (FieldContents "some-password")

-- | User can use ANSI control sequences in field contents.
-- If some ANSI control sequence contain in field contents then we append @reset@ ANSI control sequence.
-- Otherwise, we just return wrapped text.
Expand Down Expand Up @@ -189,7 +201,37 @@ deriveToJSON (aesonPrefix camelCase) ''Entry
makeLensesWith abbreviatedFields ''Entry

instance ToSchema Entry where
declareNamedSchema = genericDeclareNamedSchema $ fromAesonOptions (aesonPrefix camelCase)
declareNamedSchema proxy =
genericDeclareNamedSchema (fromAesonOptions (aesonPrefix camelCase)) proxy <&> \schema ->
schema
& Schema.schema . example ?~ toJSON exampleEntry

exampleEntry :: Entry
exampleEntry =
Entry
{ ePath = exampleEntryPath
, eDateModified = exampleDate
, eMasterField = Nothing
, eFields = HS.fromList
[ ( UnsafeFieldName "username"
, Field
{ fDateModified = exampleDate
, fVisibility = Public
, fContents = FieldContents "some-username"
}
)
, ( UnsafeFieldName "password"
, Field
{ fDateModified = exampleDate
, fVisibility = Private
, fContents = FieldContents "some-password"
}
)
]
, eTags = S.singleton exampleEntryTag
}
where
exampleDate = UTCTime (fromGregorian 2016 7 22) 0

newEntry :: EntryPath -> UTCTime -> Entry
newEntry path time =
Expand Down

0 comments on commit 6ae301a

Please sign in to comment.