Alex Mikhalev
7 years ago
13 changed files with 289 additions and 179 deletions
@ -0,0 +1,49 @@ |
|||||||
|
import { Duration } from "./Duration"; |
||||||
|
|
||||||
|
export interface WithType<Type extends string = string> { |
||||||
|
type: Type; |
||||||
|
} |
||||||
|
|
||||||
|
export interface WithProgram { programId: number; } |
||||||
|
|
||||||
|
export type RunProgramRequest = WithProgram & WithType<"runProgram">; |
||||||
|
export type CancelProgramRequest = WithProgram & WithType<"cancelProgram">; |
||||||
|
|
||||||
|
export type UpdateProgramData = WithProgram & { data: any }; |
||||||
|
export type UpdateProgramRequest = UpdateProgramData & WithType<"updateProgram">; |
||||||
|
export type UpdateProgramResponse = Response<"updateProgram", { data: any }>; |
||||||
|
|
||||||
|
export interface WithSection { sectionId: number; } |
||||||
|
|
||||||
|
export type RunSectionData = WithSection & { duration: Duration }; |
||||||
|
export type RunSectionReqeust = RunSectionData & WithType<"runSection">; |
||||||
|
export type RunSectionResponse = Response<"runSection", { runId: number }>; |
||||||
|
|
||||||
|
export type CancelSectionRequest = WithSection & WithType<"cancelSection">; |
||||||
|
|
||||||
|
export interface CancelSectionRunIdData { runId: number; } |
||||||
|
export type CancelSectionRunIdRequest = CancelSectionRunIdData & WithType<"cancelSectionRunId">; |
||||||
|
|
||||||
|
export interface PauseSectionRunnerData { paused: boolean; } |
||||||
|
export type PauseSectionRunnerRequest = PauseSectionRunnerData & WithType<"pauseSectionRunner">; |
||||||
|
|
||||||
|
export type Request = RunProgramRequest | CancelProgramRequest | UpdateProgramRequest | |
||||||
|
RunSectionReqeust | CancelSectionRequest | CancelSectionRunIdRequest | PauseSectionRunnerRequest; |
||||||
|
|
||||||
|
export type RequestType = Request["type"]; |
||||||
|
|
||||||
|
export interface SuccessResponseData<Type extends string = string> extends WithType<Type> { |
||||||
|
result: "success"; |
||||||
|
message: string; |
||||||
|
} |
||||||
|
|
||||||
|
export interface ErrorResponseData<Type extends string = string> extends WithType<Type> { |
||||||
|
result: "error"; |
||||||
|
error: string; |
||||||
|
offset?: number; |
||||||
|
code?: number; |
||||||
|
} |
||||||
|
|
||||||
|
export type Response<Type extends string = string, Res = {}> = |
||||||
|
(SuccessResponseData<Type> & Res) | |
||||||
|
(ErrorResponseData<Type>); |
@ -0,0 +1,50 @@ |
|||||||
|
import { |
||||||
|
ModelSchema, primitive, PropSchema, |
||||||
|
} from "serializr"; |
||||||
|
import * as s from ".."; |
||||||
|
|
||||||
|
export const duration: PropSchema = { |
||||||
|
serializer: (d: s.Duration | null) => |
||||||
|
d != null ? d.toSeconds() : null, |
||||||
|
deserializer: (json: any, done) => { |
||||||
|
if (typeof json === "number") { |
||||||
|
done(null, s.Duration.fromSeconds(json)); |
||||||
|
} else { |
||||||
|
done(new Error(`Duration expects a number, not ${json}`), undefined); |
||||||
|
} |
||||||
|
}, |
||||||
|
}; |
||||||
|
|
||||||
|
export const date: PropSchema = { |
||||||
|
serializer: (jsDate: Date | null) => jsDate != null ? |
||||||
|
jsDate.toISOString() : null, |
||||||
|
deserializer: (json: any, done) => { |
||||||
|
if (json === null) { |
||||||
|
return done(null, null); |
||||||
|
} |
||||||
|
try { |
||||||
|
done(null, new Date(json)); |
||||||
|
} catch (e) { |
||||||
|
done(e, undefined); |
||||||
|
} |
||||||
|
}, |
||||||
|
}; |
||||||
|
|
||||||
|
export const dateOfYear: ModelSchema<s.DateOfYear> = { |
||||||
|
factory: () => new s.DateOfYear(), |
||||||
|
props: { |
||||||
|
year: primitive(), |
||||||
|
month: primitive(), // this only works if it is represented as a # from 0-12
|
||||||
|
day: primitive(), |
||||||
|
}, |
||||||
|
}; |
||||||
|
|
||||||
|
export const timeOfDay: ModelSchema<s.TimeOfDay> = { |
||||||
|
factory: () => new s.TimeOfDay(), |
||||||
|
props: { |
||||||
|
hour: primitive(), |
||||||
|
minute: primitive(), |
||||||
|
second: primitive(), |
||||||
|
millisecond: primitive(), |
||||||
|
}, |
||||||
|
}; |
@ -0,0 +1,65 @@ |
|||||||
|
import { createSimpleSchema, deserialize, ModelSchema, object, primitive, serialize } from "serializr"; |
||||||
|
import * as requests from "../requests"; |
||||||
|
import * as common from "./common"; |
||||||
|
|
||||||
|
export const withType: ModelSchema<requests.WithType> = createSimpleSchema({ |
||||||
|
type: primitive(), |
||||||
|
}); |
||||||
|
|
||||||
|
export const withProgram: ModelSchema<requests.WithProgram> = createSimpleSchema({ |
||||||
|
...withType.props, |
||||||
|
programId: primitive(), |
||||||
|
}); |
||||||
|
|
||||||
|
export const withSection: ModelSchema<requests.WithSection> = createSimpleSchema({ |
||||||
|
...withType.props, |
||||||
|
sectionId: primitive(), |
||||||
|
}); |
||||||
|
|
||||||
|
export const updateProgramData: ModelSchema<requests.UpdateProgramData> = createSimpleSchema({ |
||||||
|
...withProgram.props, |
||||||
|
data: object(createSimpleSchema({ "*": true })), |
||||||
|
}); |
||||||
|
|
||||||
|
export const runSection: ModelSchema<requests.RunSectionData> = createSimpleSchema({ |
||||||
|
...withSection.props, |
||||||
|
duration: common.duration, |
||||||
|
}); |
||||||
|
|
||||||
|
export const cancelSectionRunId: ModelSchema<requests.CancelSectionRunIdData> = createSimpleSchema({ |
||||||
|
...withType.props, |
||||||
|
runId: primitive(), |
||||||
|
}); |
||||||
|
|
||||||
|
export const pauseSectionRunner: ModelSchema<requests.PauseSectionRunnerData> = createSimpleSchema({ |
||||||
|
...withType.props, |
||||||
|
paused: primitive(), |
||||||
|
}); |
||||||
|
|
||||||
|
export function getRequestSchema(request: requests.WithType): ModelSchema<any> { |
||||||
|
switch (request.type as requests.RequestType) { |
||||||
|
case "runProgram": |
||||||
|
case "cancelProgram": |
||||||
|
return withProgram; |
||||||
|
case "updateProgram": |
||||||
|
throw new Error("updateProgram not implemented"); |
||||||
|
case "runSection": |
||||||
|
return runSection; |
||||||
|
case "cancelSection": |
||||||
|
return withSection; |
||||||
|
case "cancelSectionRunId": |
||||||
|
return cancelSectionRunId; |
||||||
|
case "pauseSectionRunner": |
||||||
|
return pauseSectionRunner; |
||||||
|
default: |
||||||
|
throw new Error(`Cannot serialize request with type "${request.type}"`); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
export function seralizeRequest(request: requests.Request): any { |
||||||
|
return serialize(getRequestSchema(request), request); |
||||||
|
} |
||||||
|
|
||||||
|
export function deserializeRequest(json: any): requests.Request { |
||||||
|
return deserialize(getRequestSchema(json), json); |
||||||
|
} |
Loading…
Reference in new issue