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

Lofi.Schema.Output.Mongoose

Functions

createModelCode : Schema -> String

Generates JavaScript code creating a mongoose.Schema

module Lofi.Schema.Output.Mongoose exposing
  ( createModelCode
  )

{-|

# Functions
@docs createModelCode
-}

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

createModelCodeFold : Item -> List (Int, (String, String)) -> List (Int, (String, String))
createModelCodeFold item list =
  let
    base =
      case item.kind of
        Text { maximumLength } ->
          [ Just ("type", "String"), Maybe.map (\n -> ("maxlength", toString n)) maximumLength ]
        Number { real, allowNegative } ->
          [ Just ("type", "Number") ]
        Date { time } ->
          [ Just ("type", "Date") ]
    
    propertyName =
      underscored item.name

    requiredPair =
      if item.optional then
        Nothing
      else
        Just ("required", "true")
    
    defaultPair =
      case item.kind of
        Text { default } ->
          Maybe.map (\default -> ("default", (quote default))) default
        Number { default } ->
          Maybe.map (\default -> ("default", (toString default))) default
        Date { time, defaultIsNow } ->
          if time && defaultIsNow then
            Just ("default", "Date.now")
          else
            Nothing
    
    schemaString =
      base ++ [ defaultPair, requiredPair ]
      |> List.filterMap identity
      |> pairsToJSObject False

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

{-| Generates JavaScript code creating a mongoose.Schema -}
createModelCode : Schema -> String
createModelCode schema =
  let
    constantName =
      schema.collectionName ++ "_schema"
      |> lowerCamelize

    fields =
      List.foldr createModelCodeFold [] schema.items
      |> List.sortBy Tuple.first
      |> List.map Tuple.second
      |> pairsToJSObject True
    
    schemaOptions =
      pairsToJSObject True
        [ ("collection", schema.collectionName |> lowerCamelize |> quote )
        ]
  in
    "const " ++ constantName ++ " = " ++
    "new mongoose.Schema(" ++ fields ++ ", " ++ schemaOptions ++");"