@ -9,11 +9,10 @@
* /
import {
ScheduleRequest ,
ValidationResult ,
type ValidationResult ,
ErrorCode ,
PriorityType ,
PermissionType
type PriorityType ,
type PermissionType
} from './bridge'
export class SchemaValidator {
@ -21,37 +20,48 @@ export class SchemaValidator {
/ * *
* Validate schedule request input
* /
validateScheduleRequest ( request : any ) : ValidationResult {
validateScheduleRequest ( request : unknown ) : ValidationResult {
const errors : string [ ] = [ ]
// Type guard: ensure request is an object
if ( ! request || typeof request !== 'object' ) {
return {
isValid : false ,
errors : [ 'Request must be an object' ] ,
message : 'Request must be an object'
}
}
const req = request as Record < string , unknown >
// Validate time format (HH:mm)
if ( ! this . isValidTimeFormat ( request . time ) ) {
if ( ! this . isValidTimeFormat ( req . time as string ) ) {
errors . push ( 'Time must be in HH:mm format (24-hour)' )
}
// Validate title length (enforce exactly: title ≤ 100 chars)
if ( request . title && request . title . length > 100 ) {
if ( req . title && typeof req . title === 'string' && req . title . length > 100 ) {
errors . push ( 'Title must be 100 characters or less' )
}
// Validate body length (enforce exactly: body ≤ 500 chars)
if ( request . body && request . body . length > 500 ) {
if ( req . body && typeof req . body === 'string' && req . body . length > 500 ) {
errors . push ( 'Body must be 500 characters or less' )
}
// Validate boolean fields
if ( typeof request . sound !== 'boolean' ) {
if ( typeof req . sound !== 'boolean' ) {
errors . push ( 'Sound must be a boolean' )
}
// Validate priority
if ( ! this . isValidPriority ( request . priority ) ) {
if ( ! this . isValidPriority ( req . priority ) ) {
errors . push ( 'Priority must be low, default, or high' )
}
// Reject unknown fields
const allowedFields = [ 'time' , 'title' , 'body' , 'sound' , 'priority' ]
const unknownFields = Object . keys ( request ) . filter ( key = > ! allowedFields . includes ( key ) )
const unknownFields = Object . keys ( req ) . filter ( key = > ! allowedFields . includes ( key ) )
if ( unknownFields . length > 0 ) {
errors . push ( ` Unknown fields: ${ unknownFields . join ( ', ' ) } ` )
}
@ -66,14 +76,15 @@ export class SchemaValidator {
/ * *
* Validate permission status response
* /
validatePermissionStatus ( status : any ) : ValidationResult {
validatePermissionStatus ( status : unknown ) : ValidationResult {
const errors : string [ ] = [ ]
const statusObj = status as Record < string , unknown >
if ( ! this . isValidPermissionType ( status . notifications ) ) {
if ( ! this . isValidPermissionType ( statusObj . notifications ) ) {
errors . push ( 'Notifications permission must be granted or denied' )
}
if ( typeof status . notificationsEnabled !== 'boolean' ) {
if ( typeof statusObj . notificationsEnabled !== 'boolean' ) {
errors . push ( 'NotificationsEnabled must be a boolean' )
}
@ -87,18 +98,19 @@ export class SchemaValidator {
/ * *
* Validate notification status response
* /
validateNotificationStatus ( status : any ) : ValidationResult {
validateNotificationStatus ( status : unknown ) : ValidationResult {
const errors : string [ ] = [ ]
const statusObj = status as Record < string , unknown >
if ( typeof status . isEnabled !== 'boolean' ) {
if ( typeof statusObj . isEnabled !== 'boolean' ) {
errors . push ( 'IsEnabled must be a boolean' )
}
if ( typeof status . isScheduled !== 'boolean' ) {
if ( typeof statusObj . isScheduled !== 'boolean' ) {
errors . push ( 'IsScheduled must be a boolean' )
}
if ( typeof status . pending !== 'boolean' ) {
if ( typeof statusObj . pending !== 'boolean' ) {
errors . push ( 'Pending must be a boolean' )
}
@ -112,14 +124,15 @@ export class SchemaValidator {
/ * *
* Validate exact alarm status response
* /
validateExactAlarmStatus ( status : any ) : ValidationResult {
validateExactAlarmStatus ( status : unknown ) : ValidationResult {
const errors : string [ ] = [ ]
const statusObj = status as Record < string , unknown >
if ( typeof status . enabled !== 'boolean' ) {
if ( typeof statusObj . enabled !== 'boolean' ) {
errors . push ( 'Enabled must be a boolean' )
}
if ( typeof status . supported !== 'boolean' ) {
if ( typeof statusObj . supported !== 'boolean' ) {
errors . push ( 'Supported must be a boolean' )
}
@ -143,15 +156,15 @@ export class SchemaValidator {
/ * *
* Check if priority is valid
* /
private isValidPriority ( priority : any ) : priority is PriorityType {
return [ 'low' , 'default' , 'high' ] . includes ( priority )
private isValidPriority ( priority : unknown ) : priority is PriorityType {
return typeof priority === 'string' && [ 'low' , 'default' , 'high' ] . includes ( priority )
}
/ * *
* Check if permission type is valid
* /
private isValidPermissionType ( permission : any ) : permission is PermissionType {
return [ 'granted' , 'denied' ] . includes ( permission )
private isValidPermissionType ( permission : unknown ) : permission is PermissionType {
return typeof permission === 'string' && [ 'granted' , 'denied' ] . includes ( permission )
}
/ * *
@ -171,7 +184,7 @@ export class SchemaValidator {
/ * *
* Create success response
* /
createSuccessResponse ( data? : any ) {
createSuccessResponse ( data? : Record < string , unknown > ) {
return {
success : true ,
. . . data
@ -183,18 +196,18 @@ export class SchemaValidator {
export const schemaValidator = new SchemaValidator ( )
// Utility functions
export function validateScheduleRequest ( request : any ) : ValidationResult {
export function validateScheduleRequest ( request : unknown ) : ValidationResult {
return schemaValidator . validateScheduleRequest ( request )
}
export function validatePermissionStatus ( status : any ) : ValidationResult {
export function validatePermissionStatus ( status : unknown ) : ValidationResult {
return schemaValidator . validatePermissionStatus ( status )
}
export function validateNotificationStatus ( status : any ) : ValidationResult {
export function validateNotificationStatus ( status : unknown ) : ValidationResult {
return schemaValidator . validateNotificationStatus ( status )
}
export function validateExactAlarmStatus ( status : any ) : ValidationResult {
export function validateExactAlarmStatus ( status : unknown ) : ValidationResult {
return schemaValidator . validateExactAlarmStatus ( status )
}