From b85d9b64c7819c21a230efd7dd587218b836e095 Mon Sep 17 00:00:00 2001 From: NigeParis Date: Thu, 20 Nov 2025 20:32:23 +0100 Subject: [PATCH] WIP progress chat broadcast --- .../api/generated/.openapi-generator/FILES | 2 + .../src/api/generated/apis/OpenapiOtherApi.ts | 52 +++++++ .../generated/models/ChatTest500Response.ts | 93 ++++++++++++ frontend/src/api/generated/models/index.ts | 2 + frontend/src/pages/chat/chat.ts | 27 +++- src/chat/openapi.json | 137 +++++++++++++++++- src/chat/src/app.ts | 10 +- src/chat/src/routes/nginx-chat.ts | 33 ++--- src/openapi.json | 137 ++++++++++++++++++ 9 files changed, 463 insertions(+), 30 deletions(-) create mode 100644 frontend/src/api/generated/models/ChatTest500Response.ts diff --git a/frontend/src/api/generated/.openapi-generator/FILES b/frontend/src/api/generated/.openapi-generator/FILES index 513465f..b02736b 100644 --- a/frontend/src/api/generated/.openapi-generator/FILES +++ b/frontend/src/api/generated/.openapi-generator/FILES @@ -1,6 +1,8 @@ apis/OpenapiOtherApi.ts apis/index.ts index.ts +models/ChatTest200Response.ts +models/ChatTest500Response.ts models/DisableOtp200Response.ts models/DisableOtp401Response.ts models/DisableOtp500Response.ts diff --git a/frontend/src/api/generated/apis/OpenapiOtherApi.ts b/frontend/src/api/generated/apis/OpenapiOtherApi.ts index d9fa3e4..f03d19e 100644 --- a/frontend/src/api/generated/apis/OpenapiOtherApi.ts +++ b/frontend/src/api/generated/apis/OpenapiOtherApi.ts @@ -15,6 +15,8 @@ import * as runtime from '../runtime'; import type { + ChatTest200Response, + ChatTest500Response, DisableOtp200Response, DisableOtp401Response, DisableOtp500Response, @@ -46,6 +48,10 @@ import type { StatusOtp500Response, } from '../models/index'; import { + ChatTest200ResponseFromJSON, + ChatTest200ResponseToJSON, + ChatTest500ResponseFromJSON, + ChatTest500ResponseToJSON, DisableOtp200ResponseFromJSON, DisableOtp200ResponseToJSON, DisableOtp401ResponseFromJSON, @@ -127,6 +133,52 @@ export interface SigninRequest { */ export class OpenapiOtherApi extends runtime.BaseAPI { + /** + */ + async chatTestRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + + let urlPath = `/api/chat/test`; + + const response = await this.request({ + path: urlPath, + method: 'GET', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + // CHANGED: Handle all status codes defined in the OpenAPI spec, not just 2xx responses + // This allows typed access to error responses (4xx, 5xx) and other status codes. + // The code routes responses based on the actual HTTP status code and returns + // appropriately typed ApiResponse wrappers for each status code. + if (response.status === 200) { + // Object response for status 200 + return new runtime.JSONApiResponse(response, (jsonValue) => ChatTest200ResponseFromJSON(jsonValue)); + } + if (response.status === 401) { + // Object response for status 401 + return new runtime.JSONApiResponse(response, (jsonValue) => StatusOtp401ResponseFromJSON(jsonValue)); + } + if (response.status === 500) { + // Object response for status 500 + return new runtime.JSONApiResponse(response, (jsonValue) => ChatTest500ResponseFromJSON(jsonValue)); + } + // CHANGED: Throw error if status code is not handled by any of the defined responses + // This ensures all code paths return a value and provides clear error messages for unexpected status codes + // Only throw if responses were defined but none matched the actual status code + throw new runtime.ResponseError(response, `Unexpected status code: ${response.status}. Expected one of: 200, 401, 500`); + } + + /** + */ + async chatTest(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.chatTestRaw(initOverrides); + return await response.value(); + } + /** */ async disableOtpRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { diff --git a/frontend/src/api/generated/models/ChatTest500Response.ts b/frontend/src/api/generated/models/ChatTest500Response.ts new file mode 100644 index 0000000..444222b --- /dev/null +++ b/frontend/src/api/generated/models/ChatTest500Response.ts @@ -0,0 +1,93 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * @fastify/swagger + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 9.6.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +/** + * + * @export + * @interface ChatTest500Response + */ +export interface ChatTest500Response { + /** + * + * @type {string} + * @memberof ChatTest500Response + */ + kind: ChatTest500ResponseKindEnum; + /** + * + * @type {string} + * @memberof ChatTest500Response + */ + msg: ChatTest500ResponseMsgEnum; +} + + +/** + * @export + */ +export const ChatTest500ResponseKindEnum = { + Failed: 'failed' +} as const; +export type ChatTest500ResponseKindEnum = typeof ChatTest500ResponseKindEnum[keyof typeof ChatTest500ResponseKindEnum]; + +/** + * @export + */ +export const ChatTest500ResponseMsgEnum = { + ChatFailedGeneric: 'chat.failed.generic' +} as const; +export type ChatTest500ResponseMsgEnum = typeof ChatTest500ResponseMsgEnum[keyof typeof ChatTest500ResponseMsgEnum]; + + +/** + * Check if a given object implements the ChatTest500Response interface. + */ +export function instanceOfChatTest500Response(value: object): value is ChatTest500Response { + if (!('kind' in value) || value['kind'] === undefined) return false; + if (!('msg' in value) || value['msg'] === undefined) return false; + return true; +} + +export function ChatTest500ResponseFromJSON(json: any): ChatTest500Response { + return ChatTest500ResponseFromJSONTyped(json, false); +} + +export function ChatTest500ResponseFromJSONTyped(json: any, ignoreDiscriminator: boolean): ChatTest500Response { + if (json == null) { + return json; + } + return { + + 'kind': json['kind'], + 'msg': json['msg'], + }; +} + +export function ChatTest500ResponseToJSON(json: any): ChatTest500Response { + return ChatTest500ResponseToJSONTyped(json, false); +} + +export function ChatTest500ResponseToJSONTyped(value?: ChatTest500Response | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + 'kind': value['kind'], + 'msg': value['msg'], + }; +} + diff --git a/frontend/src/api/generated/models/index.ts b/frontend/src/api/generated/models/index.ts index db7a2e3..b4d967b 100644 --- a/frontend/src/api/generated/models/index.ts +++ b/frontend/src/api/generated/models/index.ts @@ -1,5 +1,7 @@ /* tslint:disable */ /* eslint-disable */ +export * from './ChatTest200Response'; +export * from './ChatTest500Response'; export * from './DisableOtp200Response'; export * from './DisableOtp401Response'; export * from './DisableOtp500Response'; diff --git a/frontend/src/pages/chat/chat.ts b/frontend/src/pages/chat/chat.ts index 59806f1..012c68c 100644 --- a/frontend/src/pages/chat/chat.ts +++ b/frontend/src/pages/chat/chat.ts @@ -3,7 +3,7 @@ import { showError } from "@app/toast"; import authHtml from './chat.html?raw'; import client from '@app/api' import { getUser, updateUser } from "@app/auth"; -import io from "socket.io-client"; +import io from 'socket.io-client'; const socket = io("wss://localhost:8888", { path: "/api/chat/socket.io/", @@ -22,7 +22,7 @@ socket.on("connect", async () => { }); // Listen for messages from the server "MsgObjectServer" -socket.on("MsgObjectServer", (data) => { +socket.on("MsgObjectServer", (data: any) => { console.log("Message Obj Recieved:", data.message); console.log("Recieved data.message.text: ", data.message.text); console.log("Recieved data.message.user: ", data.message.user); @@ -62,6 +62,17 @@ function handleChat(_url: string, _args: RouteHandlerParams): RouteHandlerReturn const bwhoami = document.getElementById('b-whoami') as HTMLButtonElement; const username = document.getElementById('username') as HTMLDivElement; + const value = await client.chatTest(); + if (value.kind === "success") { + console.log(value.payload); + } + else if (value.kind === "notLoggedIn") { + console.log('not logged in'); + } else { + console.log('unknown response: ', value); + } + + const addMessage = (text: string) => { if (!chatWindow) return; const messageElement = document.createElement("div"); @@ -71,9 +82,15 @@ function handleChat(_url: string, _args: RouteHandlerParams): RouteHandlerReturn }; // Send button - sendButton?.addEventListener("click", () => { - if (sendtextbox && sendtextbox.value.trim()) { - const msgText = sendtextbox.value.trim(); + sendButton?.addEventListener("click",() => { + + + if (sendtextbox && sendtextbox.value.trim()) { + const msgText = sendtextbox.value.trim(); + + + + addMessage(msgText); const user = getUser(); diff --git a/src/chat/openapi.json b/src/chat/openapi.json index 38cd725..8afe3d2 100644 --- a/src/chat/openapi.json +++ b/src/chat/openapi.json @@ -7,7 +7,142 @@ "components": { "schemas": {} }, - "paths": {}, + "paths": { + "/api/chat/test": { + "get": { + "operationId": "chatTest", + "responses": { + "200": { + "description": "Default Response", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "kind", + "msg", + "payload" + ], + "properties": { + "kind": { + "enum": [ + "success" + ] + }, + "msg": { + "enum": [ + "chat.success" + ] + }, + "payload": { + "type": "object", + "required": [ + "name", + "id", + "guest" + ], + "properties": { + "name": { + "type": "string" + }, + "id": { + "type": "string" + }, + "guest": { + "type": "boolean" + } + } + } + } + } + } + } + }, + "401": { + "description": "Default Response", + "content": { + "application/json": { + "schema": { + "anyOf": [ + { + "type": "object", + "required": [ + "kind", + "msg" + ], + "properties": { + "kind": { + "enum": [ + "notLoggedIn" + ] + }, + "msg": { + "enum": [ + "auth.noCookie", + "auth.invalidKind", + "auth.noUser", + "auth.invalid" + ] + } + } + }, + { + "type": "object", + "required": [ + "kind", + "msg" + ], + "properties": { + "kind": { + "enum": [ + "notLoggedIn" + ] + }, + "msg": { + "enum": [ + "auth.noCookie", + "auth.invalidKind", + "auth.noUser", + "auth.invalid" + ] + } + } + } + ] + } + } + } + }, + "500": { + "description": "Default Response", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "kind", + "msg" + ], + "properties": { + "kind": { + "enum": [ + "failed" + ] + }, + "msg": { + "enum": [ + "chat.failed.generic" + ] + } + } + } + } + } + } + } + } + } + }, "servers": [ { "url": "https://local.maix.me:8888", diff --git a/src/chat/src/app.ts b/src/chat/src/app.ts index eaf01c1..3a479b5 100644 --- a/src/chat/src/app.ts +++ b/src/chat/src/app.ts @@ -47,11 +47,11 @@ export default app; export { app }; export const color = { - red: 'x1b[31m', - green: 'x1b[32m', - yellow: 'x1b[33m', - blue: 'x1b[34m', - reset: 'x1b[0m', + red: '\x1b[31m', + green: '\x1b[32m', + yellow: '\x1b[33m', + blue: '\x1b[34m', + reset: '\x1b[0m', }; type ClientMessage = { diff --git a/src/chat/src/routes/nginx-chat.ts b/src/chat/src/routes/nginx-chat.ts index c40c1c0..d2f45ef 100644 --- a/src/chat/src/routes/nginx-chat.ts +++ b/src/chat/src/routes/nginx-chat.ts @@ -1,10 +1,6 @@ import { FastifyPluginAsync } from 'fastify'; import { MakeStaticResponse, typeResponse } from '@shared/utils'; import { Type } from '@sinclair/typebox'; -// import * as fsocketio from 'socket.io'; - - - export const ChatRes = { 200: typeResponse('success', 'chat.success', { @@ -17,20 +13,19 @@ export const ChatRes = { export type ChatResType = MakeStaticResponse; const route: FastifyPluginAsync = async (fastify): Promise => { - - // fastify.get( - // '/api/chat/test', - // { - // schema: { - // response: ChatRes, - // operationId: 'chatTest', - // }, - // config: { requireAuth: true }, - // }, - // async (req, res) => { - // console.log('/api/chat called =================>'); - // res.makeResponse(200, 'success', 'chat.success', { name: req.authUser!.name, 'id': req.authUser!.id, guest: false }); - // }, - // ); + fastify.get( + '/api/chat/test', + { + schema: { + response: ChatRes, + operationId: 'chatTest', + }, + config: { requireAuth: true }, + }, + async (req, res) => { + console.log('/api/chat called =================>'); + res.makeResponse(200, 'success', 'CCChat.success', { name: 'My_namw', 'id': req.authUser!.id, guest: false }); + }, + ); }; export default route; \ No newline at end of file diff --git a/src/openapi.json b/src/openapi.json index 6a92186..f370df1 100644 --- a/src/openapi.json +++ b/src/openapi.json @@ -1189,6 +1189,143 @@ "openapi_other" ] } + }, + "/api/chat/test": { + "get": { + "operationId": "chatTest", + "responses": { + "200": { + "description": "Default Response", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "kind", + "msg", + "payload" + ], + "properties": { + "kind": { + "enum": [ + "success" + ] + }, + "msg": { + "enum": [ + "chat.success" + ] + }, + "payload": { + "type": "object", + "required": [ + "name", + "id", + "guest" + ], + "properties": { + "name": { + "type": "string" + }, + "id": { + "type": "string" + }, + "guest": { + "type": "boolean" + } + } + } + } + } + } + } + }, + "401": { + "description": "Default Response", + "content": { + "application/json": { + "schema": { + "anyOf": [ + { + "type": "object", + "required": [ + "kind", + "msg" + ], + "properties": { + "kind": { + "enum": [ + "notLoggedIn" + ] + }, + "msg": { + "enum": [ + "auth.noCookie", + "auth.invalidKind", + "auth.noUser", + "auth.invalid" + ] + } + } + }, + { + "type": "object", + "required": [ + "kind", + "msg" + ], + "properties": { + "kind": { + "enum": [ + "notLoggedIn" + ] + }, + "msg": { + "enum": [ + "auth.noCookie", + "auth.invalidKind", + "auth.noUser", + "auth.invalid" + ] + } + } + } + ] + } + } + } + }, + "500": { + "description": "Default Response", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "kind", + "msg" + ], + "properties": { + "kind": { + "enum": [ + "failed" + ] + }, + "msg": { + "enum": [ + "chat.failed.generic" + ] + } + } + } + } + } + } + }, + "tags": [ + "openapi_other" + ] + } } }, "components": {