This is an alternative site for discovering Elm packages. You may be looking for the official Elm package site instead.

Lofi.Schema.Output.Joi

Functions

createSchemaCode : Schema -> String

Generates JavaScript code creating a Joi schema

module Lofi.Schema.Output.Joi exposing
  ( createSchemaCode
  )

{-|

# Functions
@docs createSchemaCode
-}

import Lofi.Schema exposing (Schema, Item, Kind(..))
import String.Extra exposing (underscored, camelize, decapitalize, quote)


lowerCamelize : String -> String
lowerCamelize = camelize >> decapitalize

pairsToJSObject : Bool -> List (String, String) -> String
pairsToJSObject multilined pairs =
  let
    propertyDivider =
      if multilined then ",\n  " else ", "
    
    wrapInBraces =
      if multilined then
        \s -> "{\n  " ++ s ++ "\n}"
      else
        \s -> "{ " ++ s ++ " }"
  in
    pairs
    |> List.map (\(a, b) -> a ++ ": " ++ b)
    |> String.join propertyDivider
    |> wrapInBraces

createSchemaCodeFold : Item -> List (Int, (String, String)) -> List (Int, (String, String))
createSchemaCodeFold item list =
  let
    nativeKind =
      case item.kind of
        Text { maximumLength, isEmail } ->
          let
            emailSuffix =
              if isEmail then
                ".email()"
              else
                ""
            
            maxSuffix =
              maximumLength
              |> Maybe.map (\n -> ".max(" ++ (toString n) ++ ")")
              |> Maybe.withDefault ""
          in
          "Joi.string()" ++ emailSuffix ++ maxSuffix
        Number { real, allowNegative } ->
          "Joi.number()"
        Date { time } ->
          "Joi.date()"
    
    propertyName =
      underscored item.name

    requiredString =
      if item.optional then
        ".optional()"
      else
        ".required()"
    
    schemaString =
      [ nativeKind
      , requiredString
      ]
      |> String.join ""

    field =
      (propertyName, schemaString)
    
    priority : Int
    priority =
      if item.isPrimaryKey then
        2
      else
        1
  in
    ( priority, field ) :: list

{-| Generates JavaScript code creating a Joi schema -}
createSchemaCode : Schema -> String
createSchemaCode schema =
  let
    constantName =
      schema.individualName
      |> lowerCamelize

    fields =
      List.foldr createSchemaCodeFold [] schema.items
      |> List.sortBy Tuple.first
      |> List.map Tuple.second
      |> pairsToJSObject True
  in
    "const " ++ constantName ++ " = " ++
    "Joi.object(" ++ fields ++ ");"