Skip to content

Commit

Permalink
Merge pull request #370 from HapticX/dev
Browse files Browse the repository at this point in the history
improve happyx documentation and openapi interaction
  • Loading branch information
Ethosa authored Oct 30, 2024
2 parents ebe90c0 + fb90977 commit 646a72a
Show file tree
Hide file tree
Showing 10 changed files with 131 additions and 9 deletions.
2 changes: 2 additions & 0 deletions examples/website/src/components/guide_page.nim
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ component GuidePage:
FlagsList
of "hpx_project_type":
HpxProjectType
of "websockets":
Websockets

tDiv(class = "hidden xl:flex justify-between items-center w-full pb-8"):
if guidePages[currentGuidePage]["prev"].getStr != "":
Expand Down
11 changes: 9 additions & 2 deletions examples/website/src/components/sidebar.nim
Original file line number Diff line number Diff line change
Expand Up @@ -86,11 +86,16 @@ var
"ssr_basics": {
"title": "Server-side Applications Basics 🖥",
"prev": "reactivity",
"next": "websockets"
},
"websockets": {
"title": "Websockets 🔌",
"prev": "ssr_basics",
"next": "db_access"
},
"db_access": {
"title": "Database access 📦",
"prev": "ssr_basics",
"prev": "websockets",
"next": "sqlite"
},
"sqlite": {
Expand Down Expand Up @@ -179,7 +184,7 @@ proc SideBar*(isMobile: bool = false): TagRef =
if isMobile:
"flex-col xl:flex gap-12 lg:gap-8 xl:gap-4 px-2 h-full"
else:
"flex-col hidden xl:flex gap-12 lg:gap-8 xl:gap-4 px-2 pt-8 overflow-y-auto max-h-[95vh]"
"flex-col hidden xl:flex gap-12 lg:gap-8 xl:gap-4 px-2 pt-8 overflow-y-auto max-h-[93vh]"
):
if not isMobile:
tP(class = "text-5xl lg:text-3xl xl:text-2xl font-bold text-center w-max"):
Expand Down Expand Up @@ -228,6 +233,8 @@ proc SideBar*(isMobile: bool = false): TagRef =
SideBarFolder("ssr_basics", "Server-side Applications 🖥", isMobile):
SideBarItem("ssr_basics", isMobile):
{translate"Server-side Applications Basics 🖥"}
SideBarItem("websockets", isMobile):
{translate"Websockets 🔌"}
SideBarItem("db_access", isMobile):
{translate"Database access 📦"}
SideBarItem("sqlite", isMobile):
Expand Down
4 changes: 2 additions & 2 deletions examples/website/src/docs/docs.nim
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import
./[
introduction, getting_started, happyx_app, path_params, spa_basics, ssr_basics,
tailwind_and_other, decorators, reactivity, components, ssr_docs, func_components,
spa_rendering, mounting, liveviews, flags_list, hpx_project_type
spa_rendering, mounting, liveviews, flags_list, hpx_project_type, websockets
],
./db/[
mongo, sqlite, postgres, db_access
Expand All @@ -16,5 +16,5 @@ export
introduction, getting_started, happyx_app, path_params, spa_basics, ssr_basics,
tailwind_and_other, decorators, reactivity, mongo, db_access, sqlite, postgres,
components, ssr_docs, func_components, spa_rendering, mounting, liveviews,
flags_list, hpx_project_type,
flags_list, hpx_project_type, websockets,
karax
22 changes: 22 additions & 0 deletions examples/website/src/docs/websockets.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Import HappyX
import
../../../../src/happyx,
../ui/[colors, code, play_states, translations],
../components/[
code_block_guide, code_block, code_block_slider
]


proc Websockets*(): TagRef =
buildHtml:
tDiv(class = "flex flex-col px-8 py-2 xl:h-fit gap-4"):
tH1: { translate"Websockets 🔌" }

tP:
{ translate"Like other web frameworks, in HappyX you can use websockets. Below is an example of usage." }

CodeBlock("nim", nimSsrWebsockets, "nim_ssr_websockets_ex")

tP:
{ translate"In addition to the routes used above, websockets have other routes as well. Here is the complete list of all routes:" }
CodeBlock("nim", nimSsrWebsocketsRoutes, "nim_ssr_websockets_routes")
51 changes: 51 additions & 0 deletions examples/website/src/ui/code/nim_ssr.nim
Original file line number Diff line number Diff line change
Expand Up @@ -596,4 +596,55 @@ appRoutes "app":
}
# Response cookies
outCookies.add(setCookie("Hello", "world"))
"""
nimSsrWebsockets* = """import happyx
type
Msg* = object
text: string
fromId: int
serve "127.0.0.1", 5123:
wsConnect:
echo "Connected"
ws "/listen":
try:
# wsData uses to fetch data from websocket connection
let message = wsData.parseJson().to(Msg)
# wsConnections is list of all active websocket connections
for connection in wsConnections:
if connection.readyState == Open:
await connection.send $(%*{
"text": message.text,
"fromId": message.fromId
})
except JsonParsingError:
# wsClient is current active websocket connection
await wsClient.send "failure"
"""
nimSsrWebsocketsRoutes* = """serve "127.0.0.1", 5000:
# client-server messaging
ws "/ws":
await wsClient.send("hello")
# used only when the websocket client is connected
wsConnect:
echo "New connection!"
await wsClient.send("You're welcome!")
# used when the websocket client triggers a protocol mismatch
wsMismatchProtocol:
echo "mismatch protocol"
# used when the websocket client is disconnected
wsClosed:
echo "connect is closed"
# used in other cases of websocket errors
wsError:
echo "unknown WS error"
"""
18 changes: 18 additions & 0 deletions examples/website/src/ui/translations.nim
Original file line number Diff line number Diff line change
Expand Up @@ -2654,6 +2654,24 @@ translatable:
"zh" -> "下面是您在编写应用程序时可以使用的隐藏变量的完整列表。"
"fr" -> "Voici une liste complète des variables cachées que vous pouvez utiliser lors de l'écriture d'une application."
"ko" -> "애플리케이션을 작성할 때 사용할 수 있는 숨겨진 변수의 전체 목록입니다."
"Websockets 🔌":
"ru" -> "Вебсокеты 🔌"
"ja" -> "Webソケット 🔌"
"zh" -> "Websockets 🔌"
"fr" -> "Websockets 🔌"
"ko" -> "웹소켓 🔌"
"Like other web frameworks, in HappyX you can use websockets. Below is an example of usage.":
"ru" -> "Как и остальные веб-фреймворке, в HappyX вы можете использовать вебсокеты. Ниже приведен пример использования."
"ja" -> "他のWebフレームワークと同様に、HappyXではWebソケットを使用できます。以下に使用例を示します。"
"zh" -> "与其他网络框架一样,在HappyX中您可以使用Websockets。下面是一个使用示例。"
"fr" -> "Comme dans les autres frameworks web, dans HappyX, vous pouvez utiliser des websockets. Voici un exemple d'utilisation."
"ko" -> "다른 웹 프레임워크와 마찬가지로 HappyX에서 웹소켓을 사용할 수 있습니다. 아래는 사용 예시입니다."
"In addition to the routes used above, websockets have other routes as well. Here is the complete list of all routes:":
"ru" -> "Помимо выше использованных маршрутов вебсокеты имеют и другие маршруты. Вот полный список всех маршрутов:"
"ja" -> "上記で使用したルートに加えて、Webソケットには他のルートもあります。すべてのルートの完全なリストは以下の通りです。"
"zh" -> "除了上述使用的路由外,Websockets还具有其他路由。以下是所有路由的完整列表:"
"fr" -> "En plus des routes utilisées ci-dessus, les websockets ont d'autres routes. Voici la liste complète de toutes les routes :"
"ko" -> "위에서 사용한 경로 외에도 웹소켓에는 다른 경로가 있습니다. 모든 경로의 전체 목록은 다음과 같습니다:"


var spokenLang: cstring
Expand Down
2 changes: 1 addition & 1 deletion happyx.nimble
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

description = "Macro-oriented asynchronous web-framework written with ♥"
author = "HapticX"
version = "4.6.3"
version = "4.6.4"
license = "MIT"
srcDir = "src"
installExt = @["nim"]
Expand Down
2 changes: 1 addition & 1 deletion src/happyx/core/constants.nim
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ const
# Framework version
HpxMajor* = 4
HpxMinor* = 6
HpxPatch* = 3
HpxPatch* = 4
HpxVersion* = $HpxMajor & "." & $HpxMinor & "." & $HpxPatch


Expand Down
22 changes: 21 additions & 1 deletion src/happyx/ssr/docs/autodocs.nim
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,7 @@ proc procApiDocs*(docsData: NimNode): NimNode =
"newApiDocObject",
newCall("@", bracket(newLit"GET")),
ident"documentation",
newLit"",
newDotExpr(ident"routeData", ident"path"),
newDotExpr(ident"routeData", ident"pathParams"),
newDotExpr(ident"routeData", ident"requestModels"),
Expand All @@ -225,6 +226,7 @@ proc procApiDocs*(docsData: NimNode): NimNode =
"newApiDocObject",
newDotExpr(ident"route", ident"httpMethod"),
ident"documentation",
newLit"",
newDotExpr(ident"routeData", ident"path"),
newDotExpr(ident"routeData", ident"pathParams"),
newDotExpr(ident"routeData", ident"requestModels"),
Expand Down Expand Up @@ -373,11 +375,13 @@ proc openApiDocs*(docsData: NimNode): NimNode =
"responses": {
"200": {
"description": "",
"content": {}
"content": {},
"headers": {},
}
}
}

# Parse all status codes
for m in route.src.findAll(re2"\bstatusCode\b\s*=\s*(\d+)(\s*#+\s*([^\n]+))?"):
let
statusCode = route.src[m.group(0)]
Expand All @@ -389,6 +393,22 @@ proc openApiDocs*(docsData: NimNode): NimNode =
"content": {}
}

# Parse all outHeaders
for m in route.src.findAll(re2"""\boutHeaders\b\["([^\"\]]+)"\]\s*=\s*(.*#+\s*((\d+):\s*)?([^\n]+))?"""):
let
header = route.src[m.group(0)]
statusCode = route.src[m.group(3)]
description = route.src[m.group(4)]
if statusCode == "" or statusCode notin pathData["responses"]:
for code in pathData["responses"].keys():
pathData["responses"][code]["headers"][header] = %*{
"description": description
}
else:
pathData["responses"][statusCode]["headers"][header] = %*{
"description": description
}

# echo route.srcd

# Params
Expand Down
6 changes: 4 additions & 2 deletions tests/testc15.nim
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ type
OptionsEncoding* = enum
encodingA, encodingB


model TestModel:
lang: Language

Expand Down Expand Up @@ -62,8 +61,11 @@ serve "127.0.0.1", 5000:
return {"response": m.x}

get "/teststatuscodes/{i:int}":
## you can test here status codes
outHeaders["Server"] = "HappyX " & HpxVersion ## Here just a server
if i mod 2 == 0:
statusCode = 403 ## i is not even
outHeaders["Reason"] = "bye world" ## 403: error reason
statusCode = 403 ## i is not even
return i
return i

Expand Down

0 comments on commit 646a72a

Please sign in to comment.