WIP progress chat broadcast

This commit is contained in:
NigeParis 2025-11-20 20:32:23 +01:00 committed by Maix0
parent eec27ce2e6
commit b85d9b64c7
9 changed files with 463 additions and 30 deletions

View file

@ -1,6 +1,8 @@
apis/OpenapiOtherApi.ts apis/OpenapiOtherApi.ts
apis/index.ts apis/index.ts
index.ts index.ts
models/ChatTest200Response.ts
models/ChatTest500Response.ts
models/DisableOtp200Response.ts models/DisableOtp200Response.ts
models/DisableOtp401Response.ts models/DisableOtp401Response.ts
models/DisableOtp500Response.ts models/DisableOtp500Response.ts

View file

@ -15,6 +15,8 @@
import * as runtime from '../runtime'; import * as runtime from '../runtime';
import type { import type {
ChatTest200Response,
ChatTest500Response,
DisableOtp200Response, DisableOtp200Response,
DisableOtp401Response, DisableOtp401Response,
DisableOtp500Response, DisableOtp500Response,
@ -46,6 +48,10 @@ import type {
StatusOtp500Response, StatusOtp500Response,
} from '../models/index'; } from '../models/index';
import { import {
ChatTest200ResponseFromJSON,
ChatTest200ResponseToJSON,
ChatTest500ResponseFromJSON,
ChatTest500ResponseToJSON,
DisableOtp200ResponseFromJSON, DisableOtp200ResponseFromJSON,
DisableOtp200ResponseToJSON, DisableOtp200ResponseToJSON,
DisableOtp401ResponseFromJSON, DisableOtp401ResponseFromJSON,
@ -127,6 +133,52 @@ export interface SigninRequest {
*/ */
export class OpenapiOtherApi extends runtime.BaseAPI { export class OpenapiOtherApi extends runtime.BaseAPI {
/**
*/
async chatTestRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<runtime.ApiResponse<ChatTest200Response | StatusOtp401Response | ChatTest500Response>> {
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<ChatTest200Response | StatusOtp401Response | ChatTest500Response> {
const response = await this.chatTestRaw(initOverrides);
return await response.value();
}
/** /**
*/ */
async disableOtpRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<runtime.ApiResponse<DisableOtp200Response | DisableOtp401Response | DisableOtp500Response>> { async disableOtpRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<runtime.ApiResponse<DisableOtp200Response | DisableOtp401Response | DisableOtp500Response>> {

View file

@ -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'],
};
}

View file

@ -1,5 +1,7 @@
/* tslint:disable */ /* tslint:disable */
/* eslint-disable */ /* eslint-disable */
export * from './ChatTest200Response';
export * from './ChatTest500Response';
export * from './DisableOtp200Response'; export * from './DisableOtp200Response';
export * from './DisableOtp401Response'; export * from './DisableOtp401Response';
export * from './DisableOtp500Response'; export * from './DisableOtp500Response';

View file

@ -3,7 +3,7 @@ import { showError } from "@app/toast";
import authHtml from './chat.html?raw'; import authHtml from './chat.html?raw';
import client from '@app/api' import client from '@app/api'
import { getUser, updateUser } from "@app/auth"; import { getUser, updateUser } from "@app/auth";
import io from "socket.io-client"; import io from 'socket.io-client';
const socket = io("wss://localhost:8888", { const socket = io("wss://localhost:8888", {
path: "/api/chat/socket.io/", path: "/api/chat/socket.io/",
@ -22,7 +22,7 @@ socket.on("connect", async () => {
}); });
// Listen for messages from the server "MsgObjectServer" // 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("Message Obj Recieved:", data.message);
console.log("Recieved data.message.text: ", data.message.text); console.log("Recieved data.message.text: ", data.message.text);
console.log("Recieved data.message.user: ", data.message.user); 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 bwhoami = document.getElementById('b-whoami') as HTMLButtonElement;
const username = document.getElementById('username') as HTMLDivElement; 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) => { const addMessage = (text: string) => {
if (!chatWindow) return; if (!chatWindow) return;
const messageElement = document.createElement("div"); const messageElement = document.createElement("div");
@ -71,9 +82,15 @@ function handleChat(_url: string, _args: RouteHandlerParams): RouteHandlerReturn
}; };
// Send button // Send button
sendButton?.addEventListener("click", () => { sendButton?.addEventListener("click",() => {
if (sendtextbox && sendtextbox.value.trim()) { if (sendtextbox && sendtextbox.value.trim()) {
const msgText = sendtextbox.value.trim(); const msgText = sendtextbox.value.trim();
addMessage(msgText); addMessage(msgText);
const user = getUser(); const user = getUser();

View file

@ -7,7 +7,142 @@
"components": { "components": {
"schemas": {} "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": [ "servers": [
{ {
"url": "https://local.maix.me:8888", "url": "https://local.maix.me:8888",

View file

@ -47,11 +47,11 @@ export default app;
export { app }; export { app };
export const color = { export const color = {
red: 'x1b[31m', red: '\x1b[31m',
green: 'x1b[32m', green: '\x1b[32m',
yellow: 'x1b[33m', yellow: '\x1b[33m',
blue: 'x1b[34m', blue: '\x1b[34m',
reset: 'x1b[0m', reset: '\x1b[0m',
}; };
type ClientMessage = { type ClientMessage = {

View file

@ -1,10 +1,6 @@
import { FastifyPluginAsync } from 'fastify'; import { FastifyPluginAsync } from 'fastify';
import { MakeStaticResponse, typeResponse } from '@shared/utils'; import { MakeStaticResponse, typeResponse } from '@shared/utils';
import { Type } from '@sinclair/typebox'; import { Type } from '@sinclair/typebox';
// import * as fsocketio from 'socket.io';
export const ChatRes = { export const ChatRes = {
200: typeResponse('success', 'chat.success', { 200: typeResponse('success', 'chat.success', {
@ -17,20 +13,19 @@ export const ChatRes = {
export type ChatResType = MakeStaticResponse<typeof ChatRes>; export type ChatResType = MakeStaticResponse<typeof ChatRes>;
const route: FastifyPluginAsync = async (fastify): Promise<void> => { const route: FastifyPluginAsync = async (fastify): Promise<void> => {
fastify.get(
// fastify.get( '/api/chat/test',
// '/api/chat/test', {
// { schema: {
// schema: { response: ChatRes,
// response: ChatRes, operationId: 'chatTest',
// operationId: 'chatTest', },
// }, config: { requireAuth: true },
// config: { requireAuth: true }, },
// }, async (req, res) => {
// async (req, res) => { console.log('/api/chat called =================>');
// console.log('/api/chat called =================>'); res.makeResponse(200, 'success', 'CCChat.success', { name: 'My_namw', 'id': req.authUser!.id, guest: false });
// res.makeResponse(200, 'success', 'chat.success', { name: req.authUser!.name, 'id': req.authUser!.id, guest: false }); },
// }, );
// );
}; };
export default route; export default route;

View file

@ -1189,6 +1189,143 @@
"openapi_other" "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": { "components": {