Implement websocket server
This commit is contained in:
@@ -1,7 +1,12 @@
|
||||
/**
|
||||
* Base type for an API response format.
|
||||
*/
|
||||
import {BaseSerializer, Event, ObjectSerializer} from '../../support/bus'
|
||||
import {Awaitable, ErrorWithContext, hasOwnProperty, JSONState, uuid4} from '../../util'
|
||||
|
||||
export interface APIResponse<T> {
|
||||
eventName?: string,
|
||||
eventUuid?: string,
|
||||
success: boolean,
|
||||
message?: string,
|
||||
data?: T,
|
||||
@@ -12,6 +17,61 @@ export interface APIResponse<T> {
|
||||
}
|
||||
}
|
||||
|
||||
export function isAPIResponse(what: unknown): what is APIResponse<unknown> {
|
||||
return typeof what === 'object' && what !== null
|
||||
&& hasOwnProperty(what, 'success')
|
||||
&& typeof what.success === 'boolean'
|
||||
&& (!hasOwnProperty(what, 'message') || typeof what.message === 'string')
|
||||
&& (!hasOwnProperty(what, 'error') || (
|
||||
typeof what.error === 'object' && what.error !== null
|
||||
&& hasOwnProperty(what.error, 'name') && typeof what.error.name === 'string'
|
||||
&& hasOwnProperty(what.error, 'message') && typeof what.error.message === 'string'
|
||||
&& (!hasOwnProperty(what.error, 'stack') || (
|
||||
Array.isArray(what.error.stack) && what.error.stack.every(x => typeof x === 'string')
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
export function apiEvent<T>(response: APIResponse<T>): APIResponse<T> & Event {
|
||||
if ( !response.eventName ) {
|
||||
response.eventName = '@extollo/lib:APIResponse'
|
||||
}
|
||||
|
||||
if ( !response.eventUuid ) {
|
||||
response.eventUuid = uuid4()
|
||||
}
|
||||
|
||||
return response as APIResponse<T> & Event
|
||||
}
|
||||
|
||||
/**
|
||||
* Serializer implementation that can encode/decode APIResponse objects.
|
||||
*/
|
||||
@ObjectSerializer()
|
||||
export class APIResponseSerializer extends BaseSerializer<APIResponse<unknown>, JSONState> {
|
||||
protected decodeSerial(serial: JSONState): Awaitable<APIResponse<unknown>> {
|
||||
if ( isAPIResponse(serial) ) {
|
||||
return serial
|
||||
}
|
||||
|
||||
throw new ErrorWithContext('Could not decode API response: object is malformed')
|
||||
}
|
||||
|
||||
protected encodeActual(actual: APIResponse<unknown>): Awaitable<JSONState> {
|
||||
return actual as unknown as JSONState
|
||||
}
|
||||
|
||||
protected getName(): string {
|
||||
return '@extollo/lib:APIResponseSerializer'
|
||||
}
|
||||
|
||||
matchActual(some: APIResponse<unknown>): boolean {
|
||||
return isAPIResponse(some)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats a mesage as a successful API response.
|
||||
* @param {string} displayMessage
|
||||
@@ -56,7 +116,7 @@ export function many<T>(records: T[]): APIResponse<{records: T[], total: number}
|
||||
* @return APIResponse
|
||||
* @param thrownError
|
||||
*/
|
||||
export function error(thrownError: string | Error): APIResponse<void> {
|
||||
export function error(thrownError: string | Error): APIResponse<undefined> {
|
||||
if ( typeof thrownError === 'string' ) {
|
||||
return {
|
||||
success: false,
|
||||
|
||||
Reference in New Issue
Block a user