include full appmetadata object in user status broadcast

This commit is contained in:
2026-02-04 19:11:30 +08:00
parent 8a7c5568c5
commit 7191035748
3 changed files with 82 additions and 10 deletions

View File

@@ -0,0 +1,51 @@
import {
IsOptional,
IsString,
MaxLength,
ValidateBy,
ValidationOptions,
} from 'class-validator';
/**
* Custom validator to ensure at least one of localized or unlocalized is a non-empty string
*/
function IsAtLeastOneNameProvided(validationOptions?: ValidationOptions) {
return ValidateBy(
{
name: 'isAtLeastOneNameProvided',
validator: {
validate(value, args) {
const object = args?.object as AppMetadataDto;
const hasLocalized =
typeof object.localized === 'string' &&
object.localized.trim().length > 0;
const hasUnlocalized =
typeof object.unlocalized === 'string' &&
object.unlocalized.trim().length > 0;
return hasLocalized || hasUnlocalized;
},
defaultMessage() {
return 'At least one of localized or unlocalized must be a non-empty string';
},
},
},
validationOptions,
);
}
export class AppMetadataDto {
@IsOptional()
@IsString()
@MaxLength(200)
@IsAtLeastOneNameProvided()
localized: string | null;
@IsOptional()
@IsString()
@MaxLength(200)
unlocalized: string | null;
@IsOptional()
@IsString()
appIconB64: string | null;
}

View File

@@ -1,4 +1,6 @@
import { IsEnum, IsNotEmpty, IsString, MaxLength } from 'class-validator';
import { IsEnum, ValidateNested } from 'class-validator';
import { Type } from 'class-transformer';
import { AppMetadataDto } from './app-metadata.dto';
export enum UserState {
IDLE = 'idle',
@@ -6,10 +8,9 @@ export enum UserState {
}
export class UserStatusDto {
@IsString()
@IsNotEmpty()
@MaxLength(100)
activeApp: string;
@ValidateNested()
@Type(() => AppMetadataDto)
appMetadata: AppMetadataDto;
@IsEnum(UserState)
state: UserState;

View File

@@ -495,7 +495,11 @@ describe('StateGateway', () => {
]);
const data: UserStatusDto = {
activeApp: 'VS Code',
appMetadata: {
localized: null,
unlocalized: 'VS Code',
appIconB64: null,
},
state: UserState.IDLE,
};
@@ -527,7 +531,11 @@ describe('StateGateway', () => {
};
const data: UserStatusDto = {
activeApp: 'VS Code',
appMetadata: {
localized: null,
unlocalized: 'VS Code',
appIconB64: null,
},
state: UserState.IDLE,
};
@@ -550,7 +558,11 @@ describe('StateGateway', () => {
};
const data: UserStatusDto = {
activeApp: 'VS Code',
appMetadata: {
localized: null,
unlocalized: 'VS Code',
appIconB64: null,
},
state: UserState.IDLE,
};
@@ -569,7 +581,11 @@ describe('StateGateway', () => {
data: {},
};
const data: UserStatusDto = {
activeApp: 'VS Code',
appMetadata: {
localized: null,
unlocalized: 'VS Code',
appIconB64: null,
},
state: UserState.IDLE,
};
@@ -598,7 +614,11 @@ describe('StateGateway', () => {
]);
const data: UserStatusDto = {
activeApp: 'VS Code',
appMetadata: {
localized: null,
unlocalized: 'VS Code',
appIconB64: null,
},
state: UserState.IDLE,
};