-
-
Notifications
You must be signed in to change notification settings - Fork 6
feat(api): 🚀 add WebSocket support and integrate new SSO adapters #688
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: canary
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| # VitNode AI Coding Agent Guidelines (Extended) | ||
|
|
||
| The repository is a monorepo for the VitNode framework, which includes a backend API, frontend documentation site, and shared packages. | ||
|
|
||
| ## Main Rules | ||
|
|
||
| - Use React 19.2, Next.js 16, TypeScript 5.9, Hono.js 4, | ||
| - Use pnpm as the runtime environment, | ||
| - Use Tailwind CSS 4 for styling, | ||
|
|
||
| ## API | ||
|
|
||
| - Please use as much as possible server-side API calls (server components, server actions), | ||
| - For client API calls, use `tanstack/react-query` hooks, | ||
|
|
||
| ## TypeScript | ||
|
|
||
| - Avoid using `any` type, | ||
| - Do not nest ternary operators, | ||
| - Avoid creating `index.ts` files for exports, instead use explicit file names, | ||
| - Use only `const` for create functions, but `function` for pages and generic functions, | ||
| - Prefer using nullish coalescing operator (`??`) instead of a logical or (`||`), as it is a safer operator, | ||
|
|
||
| ## React | ||
|
|
||
| - Don't use `React.FC`, instead explicitly type props | ||
| - Don't use `useMemo` and `useCallback`. Project has React Compiler | ||
|
|
||
| ## Animations | ||
|
|
||
| - Use `motion/react` for animations and gestures, | ||
| - Use `translate` instead of `top`/`left` for moving elements, as it is more performant | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,6 +1,7 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { serve } from "@hono/node-server"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { OpenAPIHono } from "@hono/zod-openapi"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { VitNodeAPI } from "@vitnode/core/api/config"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { createNodeWebSocket } from "@hono/node-ws"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { vitNodeApiConfig } from "./vitnode.api.config.js"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -11,7 +12,28 @@ VitNodeAPI({ | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| vitNodeApiConfig, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| serve( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const { injectWebSocket, upgradeWebSocket } = createNodeWebSocket({ app }); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const wsApp = app.get( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "/ws", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| upgradeWebSocket(c => ({ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| onOpen(event, ws) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const user = c.get("user"); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| console.log("Connection opened", event, ws, user); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| onMessage(event, ws) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| console.log(`Message from client`, event.data); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ws.send("Hello from server!"); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| onClose: () => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| console.log("Connection closed"); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| })), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+19
to
+31
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The WebSocket event handlers use
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| export type WebSocketApp = typeof wsApp; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const server = serve( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| fetch: app.fetch, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| port: 8080, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -25,3 +47,4 @@ serve( | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| injectWebSocket(server); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -19,6 +19,7 @@ | |
| "email", | ||
| "sso", | ||
| "cron", | ||
| "websocket", | ||
| "---Frontend---", | ||
| "layouts-and-pages", | ||
| "admin-page", | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -58,7 +58,7 @@ Add the Discord SSO plugin to your API routes. | |
|
|
||
| ```ts title="src/app/api/[...route]/route.ts" | ||
| // [!code ++] | ||
| import { DiscordSSOApiPlugin } from '@vitnode/core/api/plugins/sso/discord'; | ||
| import { DiscordSSOApiAdapter } from "@vitnode/core/api/plugins/sso/discord"; | ||
|
|
||
| VitNodeAPI({ | ||
| app, | ||
|
|
@@ -68,7 +68,7 @@ VitNodeAPI({ | |
| // [!code ++] | ||
| ssoAdapters: [ | ||
| // [!code ++] | ||
| new DiscordSSOApiPlugin({ | ||
| new DiscordSSOApiAdapter({ | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
| // [!code ++] | ||
| clientId: process.env.DISCORD_CLIENT_ID, | ||
| // [!code ++] | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -52,7 +52,7 @@ Add the Facebook SSO plugin to your API routes. | |
|
|
||
| ```ts title="src/app/api/[...route]/route.ts" | ||
| // [!code ++] | ||
| import { FacebookSSOApiPlugin } from '@vitnode/core/api/plugins/sso/facebook'; | ||
| import { FacebookSSOApiAdapter } from '@vitnode/core/api/plugins/sso/facebook'; | ||
|
|
||
| VitNodeAPI({ | ||
| app, | ||
|
|
@@ -62,7 +62,7 @@ VitNodeAPI({ | |
| // [!code ++] | ||
| ssoAdapters: [ | ||
| // [!code ++] | ||
| new FacebookSSOApiPlugin({ | ||
| new FacebookSSOApiAdapter({ | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
| // [!code ++] | ||
| clientId: process.env.FACEBOOK_CLIENT_ID, | ||
| // [!code ++] | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -113,7 +113,7 @@ Add the Discord SSO plugin to your API routes. | |
|
|
||
| ```ts title="src/app/api/[...route]/route.ts" | ||
| // [!code ++] | ||
| import { GoogleSSOApiPlugin } from '@vitnode/core/api/plugins/sso/google'; | ||
| import { GoogleSSOApiAdapter } from "@vitnode/core/api/plugins/sso/google"; | ||
|
|
||
| VitNodeAPI({ | ||
| app, | ||
|
|
@@ -123,7 +123,7 @@ VitNodeAPI({ | |
| // [!code ++] | ||
| ssoAdapters: [ | ||
| // [!code ++] | ||
| new GoogleSSOApiPlugin({ | ||
| new GoogleSSOApiAdapter({ | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
| // [!code ++] | ||
| clientId: process.env.GOOGLE_CLIENT_ID, | ||
| // [!code ++] | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| --- | ||
| title: WebSocket | ||
| description: xx | ||
| --- | ||
|
|
||
| test |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| { | ||
| "title": "WebSocket", | ||
| "pages": ["..."] | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This list item has a trailing comma. For clarity and grammatical correctness in documentation, it should be removed.