{"id":16971553,"url":"https://github.com/thomastjdev/mummy_utils","last_synced_at":"2025-03-21T20:16:14.894Z","repository":{"id":213824828,"uuid":"735010906","full_name":"ThomasTJdev/mummy_utils","owner":"ThomasTJdev","description":"Utility package for mummy multithreaded server","archived":false,"fork":false,"pushed_at":"2024-02-20T09:37:57.000Z","size":103,"stargazers_count":16,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-01-26T14:48:37.628Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Nim","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ThomasTJdev.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-12-23T10:49:18.000Z","updated_at":"2024-11-19T03:30:41.000Z","dependencies_parsed_at":"2023-12-23T12:51:09.690Z","dependency_job_id":"fdd9d004-90ec-45c2-9271-18e50460898e","html_url":"https://github.com/ThomasTJdev/mummy_utils","commit_stats":null,"previous_names":["thomastjdev/mummy_utils"],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ThomasTJdev%2Fmummy_utils","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ThomasTJdev%2Fmummy_utils/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ThomasTJdev%2Fmummy_utils/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ThomasTJdev%2Fmummy_utils/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ThomasTJdev","download_url":"https://codeload.github.com/ThomasTJdev/mummy_utils/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244860611,"owners_count":20522466,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-14T00:52:31.279Z","updated_at":"2025-03-21T20:16:14.846Z","avatar_url":"https://github.com/ThomasTJdev.png","language":"Nim","readme":"# mummy_utils\nUnofficial utility package for mummy thread server. Various helper\nfunctions.\n\n\n## Change log\n* Version `\u003e 0.1.0` requires `mummy` version `\u003e 0.4.0` or higher.\n* Version `== 0.8.0` supports `mummy` version `\u003e 0.3.6` or higher.\n\n## Examples\n\n```nim\nimport std/[json, options]\n\nimport mummy, mummy/routers\nimport mummy_utils\n\n\nproc indexParams(request: Request) =\n  # Named parameter from route URL\n  echo \"projectID:  \" \u0026 @\"projectID\"\n\n  # URI query param passed with ?invoiceID=123\n  echo \"invoiceID:  \" \u0026 @\"invoiceID\"\n\n  resp(Http200, %* {\"message\": \"Hello, World!\"})\n\n\nproc indexRedirect(request: Request) =\n  redirect(\"/project/123/info\")\n  # redirect(Http301, \"/project/123/info\")\n\n\nproc indexHeaders(request: Request) =\n  var headers: HttpHeaders\n  if request.cookies(\"pass\") == \"1234567890\":\n    setHeader(\"xauth\", \"secret\")\n  else:\n    resp(Http401, \"Not authorized\")\n\n  setHeader(\"Content-Type\", \"text/html\")\n  resp(Http200, headers, \"\u003ch1\u003eHello, World!\u003c/h1\u003e\")\n\n\nproc indexHead(request: Request) =\n  resp Http200\n\n\nproc indexPost(request: Request) =\n  let urlParam = @\"projectID\"\n  if urlParam == \"\":\n    resp(Http400, \"Missing projectID\")\n\n  let body = parseJson(request.body)\n\n  resp(Http200, ContentType.Text, body[\"msg\"].getStr())\n\n\nproc indexFile(request: Request) =\n  sendFile(\"filepath/\" \u0026 @\"filename\")\n\n\nproc indexMultipart(request: Request) =\n  var file: string\n  for entry in request.multipart:\n    if entry.data.isSome and entry.name == \"croppedImage\":\n      let (start, last) = entry.data.get\n      file = request.body[start .. last]\n      break\n\n  # Do something with file\n  resp Http204\n\n\nvar router: Router\nrouter.get(\"/project/@projectID/info\", indexParams)\nrouter.get(\"/redirect\", indexRedirect)\nrouter.get(\"/headers\", indexHeaders)\nrouter.head(\"/headers\", indexHead)\nrouter.post(\"/headers\", indexPost)\nrouter.get(\"/file/@filename\", indexFile)\nrouter.post(\"/multipart\", indexMultipart)\n\nlet server = newServer(router)\necho \"Serving on http://localhost:8080\"\nserver.serve(Port(8080))\n\n```\n\n\n\n# Routes\n\n## Examples\n\n```nim\nvar router: Router\nrouter.get(\"/project/@projectID/info\", indexCustom)\nrouter.post(\"/project/@projectID/info\", indexCustom)\n\nrouter.post(\"/project/@projectID/info\",\n  proc(request: Request) =\n    echo \"projectID:  \" \u0026 @\"projectID\"\n    echo \"invoiceID:  \" \u0026 @\"invoiceID\"\n    resp(Http200, \"Hello, World!\")\n)\n```\n\n\n# Request fields\n\n## Examples\n\n```nim\nRequest* = object\n  params*: StringTableRef       ## Parameters from the pattern, but also the\n                                ## query string.\n  body*: string                 ## Body of the request, only for POST.\n  headers*: HttpHeaders         ## Headers received with the request.\n                                ## Retrieving these is case insensitive.\n  multipart*: seq[MultipartEntry] ## Form data; only present for\n                                ## multipart/form-data\n  host*: string                 ## Hostname.\n  secure*: bool                 ## From X-Forwarded-Proto header.\n  path*: string                 ## Path of request.\n  query*: string                ## Query string of request.\n  cookies*: StringTableRef      ## Cookies from the browser.\n  ip*: string                   ## IP address of the requesting client.\n  reqMeth*: HttpMethod          ## Request method, eg. HttpGet, HttpPost\n\necho request.body\necho request.headers[\"Content-Type\"]\necho request.host\necho request.ip\necho request.path\necho request.query\necho request.reqMethod\necho request.secure\necho request.cookies(\"glid\")\necho request.cookies.hasKey(\"glid\")\n```\n\n\n## Request fields\n\n\n```nim\nproc body*(request: Request): string =\n```\n\n\n\n```nim\nproc host*(request: Request): string =\n```\n\n\n\n```nim\nproc ip*(request: Request): string =\n```\n\n\n\n```nim\nproc path*(request: Request): string =\n```\n\n\n\n```nim\nproc query*(request: Request): string =\n```\n\n\n\n```nim\nproc reqMethod*(request: Request): HttpMethod =\n```\n\n\n\n\n```nim\nproc multipart*(request: Request): seq[MultipartEntry] =\n```\n\n\n\n\n```nim\nproc secure*(request: Request): bool =\n```\n\n\n\n\n# Headers\n\n## Examples\n\n```nim\necho request.headers[\"Content-Type\"]\necho request.headers[\"Content-Typexxx\"] # returns empty string\nvar headers: HttpHeaders\nsetHeader(\"Content-Type\", \"text/plain\")\n```\n\n## Headers\n\n```nim\nproc hasKey*(headers: HttpHeaders, key: string): bool =\n```\n\n```nim\ntemplate setHeader*(field, value: string) =\n```\n\nSet header of response. Requires you to initialize the header first.\n\n\n\n# Cookies\n\n## Examples\n\n```nim\necho request.cookies(\"glid\")\necho request.cookies.hasKey(\"glid\")\nlet c = request.cookies\necho c[\"glid\"]\n```\n\n## cookies*\n\n\n\n```nim\nproc cookies*(request: Request, cookie: string): string =\n```\n\n```nim\nproc cookies*(request: Request): StringTableRef =\n```\n\nGet cookies of request.\n\n\n## setCookie*\n\n```nim\ntemplate setCookie*(\n    key, value: string,\n    domain = \"\", path = \"\", expires = \"\";\n    noName = false, secure = true, httpOnly = true,\n    maxAge = none(int),\n    sameSite = SameSite.Default\n  ) =\n```\n\nAdd cookie to response but requires the header to be available.\n\n\n## setCookie*\n\n```nim\ntemplate setCookie*(\n    key, value: string,\n    expires: DateTime | Time,\n    domain = \"\", path = \"\",\n    noName = false, secure = true, httpOnly = true,\n    maxAge = none(int),\n    sameSite = SameSite.Default\n  ) =\n```\n\nAdd cookie to response but requires the header to be available.\n\n\n# Params\n\n## Examples\n\n```nim\necho request.params(\"projectID\")\necho request.params(\"invoiceID\")\n\nlet p = request.params\necho p[\"projectID\"]\necho p.hasKey(\"invoiceID\")\n```\n\n## params*\n\n\n```nim\ntemplate params*(request: Request, s: string): string =\n```\n\n```nim\ntemplate params*(request: Request): StringTableRef =\n```\n\nGet params. Is initialized on each call.  Includes named route parameters. Returns the value on first\nmatch in this order:\n1. URI path\n2. URI query\n2. body data\n\n`URI path` names parameters are only available in main route `Details` callback\nis available.\n\n\n## `@`*\n\n```nim\necho @\"projectID\"\necho @\"invoiceID\"\n```\n\n```nim\ntemplate `@`*(s: string): untyped =\n```\n\nGet param. Includes named route parameters. Returns the value on first\nmatch in this order:\n1. URI path\n2. URI query\n2. body data\n\n`URI path` names parameters are only available in main route `Details` callback\nis available.\n\n\n\n\n# Responses\n\n## Examples\n\n```nim\nresp(\"Hello, World!\")\nresp(Http200, \"Hello, World!\")\nresp(Http200, ContentType.Html, \"Hello, World!\")\nresp(Http200, @{\"Content-Type\": \"text/plain\"}, \"Hello, World!\")\n```\n```nim\nresp(%* {\"message\": \"Hello, World!\"})\nresp(Http200, %* {\"message\": \"Hello, World!\"})\nresp(Http200, ContentType.Json, %* {\"message\": \"Hello, World!\"})\n```\n```nim\nredirect(\"/project/123/info\")\nredirect(Http301, \"/project/123/info\")\n```\n```nim\nsendFile(\"images/logo.png\")\n```\n```nim\nvar headers: HttpHeaders\nsetHeader(\"xauth\", \"1234567890\")\nsetHeader(\"Content-Type\", \"text/html\")\nresp(Http200, headers, \"Hello, World!\")\n\n# or\n\nvar headers: HttpHeaders\nsetHeader(\"xauth\", \"1234567890\")\nresp(Http200, \"Hello, World!\")\n```\n\n\n## ContentType*\n\n\n```nim\n  ContentType* = enum\n    Json = \"application/json\"\n    Text = \"text/plain\"\n    Html = \"text/html; charset=utf-8\"\n```\n\n\n\n## resp*() - string\n\nIf the `headers` is declared, they will be used in the `resp()`.\n\n\n```nim\ntemplate resp*(body: string) =\n```\n\n```nim\ntemplate resp*(httpStatus: HttpCode) =\n```\n\n\n```nim\ntemplate resp*(httpStatus: HttpCode, body: string) =\n```\n\n\n\n```nim\ntemplate resp*(httpStatus: HttpCode, contentType: ContentType, body: string) =\n```\n\n\n\n```nim\ntemplate resp*(httpStatus: HttpCode = Http200, headers: HttpHeaders, body: string) =\n```\n\n\n## resp*() - JsonNode\n\n```nim\ntemplate resp*(body: JsonNode) =\n```\n\n\n```nim\ntemplate resp*(httpStatus: HttpCode, body: JsonNode) =\n```\n\n\n```nim\ntemplate resp*(httpStatus: HttpCode, contentType: ContentType, body: JsonNode) =\n```\n\n\n## sendFile*() -\n\n```nim\ntemplate sendFile*(path: string) =\n```\n\n\n## redirect*\n\n\n```nim\ntemplate redirect*(path: string) =\n```\n\n\n```nim\ntemplate redirect*(httpStatus: HttpCode, path: string) =\n```\n\n\n# Converting existing routes from jester =\u003e mummy\n\n`mummy_utils` was developed to ease the transition from `jester` to `mummy`.\nIn `mummy_utils` you have access to many of the same sugar functions\nthat `jester` provides.\n\n## Examples\n\n**Jester**\n```nim\nroutes:\n  get \"/project/@projectID/info\":\n    echo \"projectID:  \" \u0026 @\"projectID\"\n    resp \"Hello, World!\"\n```\n\n**Mummy #1**\n```nim\nvar router: Router\nrouter.get(\"/project/@projectID/info\",\n  proc(request: Request) =\n    echo \"projectID:  \" \u0026 @\"projectID\"\n    resp \"Hello, World!\"\n)\n```\n\n**Mummy #2**\n```nim\nvar router: Router\nrouter.get(\"/project/@projectID/info\", proc(request: Request) =\n  echo \"projectID:  \" \u0026 @\"projectID\"\n  resp \"Hello, World!\"\n)\n```\n\n**Mummy #3**\n```nim\nproc indexCustom(request: Request) =\n  echo \"projectID:  \" \u0026 @\"projectID\"\n  resp \"Hello, World!\"\n\nvar router: Router\nrouter.get(\"/project/@projectID/info\", indexCustom)\n```","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthomastjdev%2Fmummy_utils","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fthomastjdev%2Fmummy_utils","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthomastjdev%2Fmummy_utils/lists"}