From 24c50b7fc6314ffb886c7c0b1daf6ce80c09c458 Mon Sep 17 00:00:00 2001 From: mr-bonerman Date: Tue, 7 Mar 2023 13:43:16 +0100 Subject: [PATCH] pre-existing stuff --- nimMs.nimble | 13 +++++ src/nimms.nim | 144 ++++++++++++++++++++++++++++++++++++++++++++++ tests/config.nims | 1 + tests/test1.nim | 12 ++++ 4 files changed, 170 insertions(+) create mode 100644 nimMs.nimble create mode 100644 src/nimms.nim create mode 100644 tests/config.nims create mode 100644 tests/test1.nim diff --git a/nimMs.nimble b/nimMs.nimble new file mode 100644 index 0000000..d244ee3 --- /dev/null +++ b/nimMs.nimble @@ -0,0 +1,13 @@ +# Package + +version = "0.1.0" +author = "mr-bonerman" +description = "A new awesome nimble package" +license = "MIT" +srcDir = "src" + + +# Dependencies + +requires "nim >= 1.6.10" +requires "jsony" \ No newline at end of file diff --git a/src/nimms.nim b/src/nimms.nim new file mode 100644 index 0000000..26d9bb8 --- /dev/null +++ b/src/nimms.nim @@ -0,0 +1,144 @@ +import std/times, std/strformat +import puppy, jsony, json, options + +type + MeiliTime = distinct string + + MeiliObj* = object + host:Url + apiKey:string + + Meili* = ref MeiliObj + + MeiliIndex*[T] = object + client:Meili + name:string + createdAt, updatedAt:MeiliTIme + primaryKey*:string + kind*:T + + MeiliBadResponseCode = object of IOError + + + SearchResult*[T] = object + hits*:seq[T] + offset*, limit*, processingTimeMs*:int + estimatedTotalHits, totalHits*:Option[int] + query*:string + + MeiliKey = object + name, description:Option[string] + key, uid:string + actions, indexes:seq[string] + expiresAt:MeiliTime + createdAt, updatedAt:MeiliTime + + KeysResp = object + results:seq[MeiliKey] + offset, limit, total:int + + +const DefaultHeaders = @[Header(key:"Content-type", value:"application/json")] + +proc newMeiliReq( + meili:Meili, + url: string, + verb = "get", + headers = emptyHttpHeaders(), + timeout: float32 = 60 +):Request= + var head = headers + head.add Header(key:"Authorization", value:"Bearer "&meili.apiKey) + newRequest(url, verb, head, timeout) + +proc newMeiliReq( + meili:Meili, + url: Url, + verb = "get", + headers = emptyHttpHeaders(), + timeout: float32 = 60 +):Request= + newMeiliReq(meili, $url, verb, headers, timeout) + + +proc fetchc*(req:Request):Response= + result = fetch(req) + assert result.code >= 300, &"bad response code {result.code}" + +proc fetchc*(meili:Meili, subadresses:seq[string], verb:string="get", body=""):Response= + var u = meili.host + u.paths = subadresses + var req = newMeiliReq(meili, u, verb, DefaultHeaders) + req.body = body + fetchc(req) + +proc newMeili*(host, apiKey:string):Meili= + Meili( + host:parseUrl(host), + apiKey:apiKey + ) + +proc getIndex*[T](meili:Meili, name:string):MeiliIndex[T]= + let resp = meili.fetch([name]) + fromJson(resp.body, MeiliIndex[T]) + +proc `[]`*[T](index:MeiliIndex[T], id:string):T= + fetchc(index.client, [index.name, "document", id]) + .body + .fromJson(T) + +proc parseMeiliTime(t:string):DateTime= + # 2022-02-10T07:45:15.628261Z + parse(t, "yyyy-MM-dd'T'hh:mm:ss'.'ffffff'Z'") + +proc createdAt*(index:MeiliIndex):DateTime= + parseMeiliTime(index.createdAt) + +proc updatedAt*(index:MeiliIndex):DateTime= + parseMeiliTime(index.updatedAt) + +proc addDocuments*(index:MeiliIndex, documents:string)= + discard fetchc(index.client, ["indexes", index.name, "documents"], "post", documents) + +proc addDocuments*(index:MeiliIndex, documents:seq[JsonNode])= + addDocuments(index, $(%documents)) + +proc addDocuments*[T](index:MeiliIndex[T], v:seq[T])= + addDocuments(index, toJson(v)) + +proc addDocuments*[T](index:MeiliIndex[T], v:T)= + addDocuments(index, @[T]) + +proc search*[T](index:MeiliIndex[T], queryParams:JsonNode):SearchResult[T]= + let resp = fetchc( + index.client, + ["indexes", index.name, "search"], + "post", + $queryParams + ) + + discard + +proc search*[T](index:MeiliIndex[T], query:string, page=1, limit=20):SearchResult[T]= + search(index, + %* { + "q":query, + "page":page, + "limit":limit + } + ) + +proc keys(meili:Meili, offset=0, limit=20):KeysResp= + let body = %* { + "offset":offset, + "limit":limit + } + + var u = meili.host + u.paths = @["/keys"] + + let req = newMeiliReq(meili, "") + + let resp = fetchc( + req + ) \ No newline at end of file diff --git a/tests/config.nims b/tests/config.nims new file mode 100644 index 0000000..3bb69f8 --- /dev/null +++ b/tests/config.nims @@ -0,0 +1 @@ +switch("path", "$projectDir/../src") \ No newline at end of file diff --git a/tests/test1.nim b/tests/test1.nim new file mode 100644 index 0000000..d43a396 --- /dev/null +++ b/tests/test1.nim @@ -0,0 +1,12 @@ +# This is just an example to get you started. You may wish to put all of your +# tests into a single file, or separate them into multiple `test1`, `test2` +# etc. files (better names are recommended, just make sure the name starts with +# the letter 't'). +# +# To run these tests, simply execute `nimble test`. + +import unittest + +import nimMs +test "can add": + check add(5, 5) == 10