diff --git a/examples/.gitignore b/examples/.gitignore index 2cacfa9..0ac007f 100644 --- a/examples/.gitignore +++ b/examples/.gitignore @@ -1,7 +1,4 @@ basic_in.ur *.exe *.sql -slackSecrets.ur -zoomSecrets.ur -oidcSecrets.ur -dropboxSecrets.ur +*Secrets.ur diff --git a/examples/zenefitsDemo.ur b/examples/zenefitsDemo.ur new file mode 100644 index 0000000..4757168 --- /dev/null +++ b/examples/zenefitsDemo.ur @@ -0,0 +1,11 @@ +(* For this demo, it's necessary to create zenefitsScrets.ur, + * defining [api_token]. *) +structure Z = Zenefits.Make(Zenefits.TwoLegged(ZenefitsSecrets)) + +fun main () = + ps <- Z.People.list; + return + + diff --git a/examples/zenefitsDemo.urp b/examples/zenefitsDemo.urp new file mode 100644 index 0000000..cfed0cd --- /dev/null +++ b/examples/zenefitsDemo.urp @@ -0,0 +1,10 @@ +library ../src/ur +rewrite all ZenefitsDemo/* +database dbname=zenefitsDemo +sql zenefitsDemo.sql +safeGetDefault +allow url https://* +prefix http://localhost:8080/ + +zenefitsSecrets +zenefitsDemo diff --git a/examples/zenefitsDemo.urs b/examples/zenefitsDemo.urs new file mode 100644 index 0000000..6ac44e0 --- /dev/null +++ b/examples/zenefitsDemo.urs @@ -0,0 +1 @@ +val main : unit -> transaction page diff --git a/src/ur/lib.urp b/src/ur/lib.urp index 6d1171a..288e931 100644 --- a/src/ur/lib.urp +++ b/src/ur/lib.urp @@ -23,3 +23,4 @@ salesforce slack zoom openIdConnect +zenefits diff --git a/src/ur/zenefits.ur b/src/ur/zenefits.ur new file mode 100644 index 0000000..1958f18 --- /dev/null +++ b/src/ur/zenefits.ur @@ -0,0 +1,70 @@ +open Json +open Urls + +functor TwoLegged(M : sig + val api_token : string + end) = struct + open M + + val token = return (Some api_token) +end + +type person = { + FirstName : option string, + PreferredName : option string, + LastName : option string, + WorkEmail : option string, + PersonalEmail : option string +} +val _ : json person = json_record + {FirstName = "first_name", + PreferredName = "preferred_name", + LastName = "last_name", + WorkEmail = "work_email", + PersonalEmail = "personal_email"} + +type subresults a = { + Data : list a, + NextUrl : option string +} +fun json_subresults [a] (_ : json a) : json (subresults a) = + json_record {Data = "data", NextUrl = "next_url"} + +type results a = { + Data : subresults a +} +fun json_results [a] (_ : json a) : json (results a) = + json_record {Data = "data"} + +functor Make(M : sig + val token : transaction (option string) + end) = struct + val token = + tok <- M.token; + case tok of + Some tok => return tok + | None => error How odd: no Zenefits token! + + val urlPrefix = "https://api.zenefits.com/" + + fun api url = + tok <- token; + WorldFfi.get url (Some ("Bearer " ^ tok)) True + + fun apiPaged' [a] (_ : json a) (url : url) : transaction (list a) = + s <- api url; + debug (show url ^ " -> " ^ s); + r <- return (fromJson s : results a); + case r.Data.NextUrl of + None => return r.Data.Data + | Some nu => + r' <- apiPaged' (bless nu); + return (List.append r.Data.Data r') + + fun apiPaged [a] (_ : json a) (url : string) : transaction (list a) = + apiPaged' (bless (urlPrefix ^ url)) + + structure People = struct + val list = apiPaged "core/people" + end +end diff --git a/src/ur/zenefits.urs b/src/ur/zenefits.urs new file mode 100644 index 0000000..5ea027f --- /dev/null +++ b/src/ur/zenefits.urs @@ -0,0 +1,25 @@ +functor TwoLegged(M : sig + val api_token : string + end) : sig + val token : transaction (option string) +end + +(** * Person API records *) + +type person = { + FirstName : option string, + PreferredName : option string, + LastName : option string, + WorkEmail : option string, + PersonalEmail : option string +} + +(** * Now for the actual methods.... *) + +functor Make(M : sig + val token : transaction (option string) + end) : sig + structure People : sig + val list : transaction (list person) + end +end