Skip to content

Commit

Permalink
Update Payload to use Ajv
Browse files Browse the repository at this point in the history
This corrects a mistake in the deserialization typeguards related to
decoded Buffer data.  It also updates Payload to use the new
ValidationError which exposes more detail about what exactly is going
wrong on a failure.

Issue #166
  • Loading branch information
slifty committed Jun 20, 2022
1 parent b60d311 commit dd8a111
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 12 deletions.
39 changes: 30 additions & 9 deletions src/classes/Payload.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,36 @@
import { ajv } from '../tools/ajv'
import { isPayloadParameters } from '../types'
import { ValidationError } from '../errors'
import type { JSONSchemaType } from 'ajv'
import type {
PayloadParameters,
PayloadType,
} from '../types'

interface JsonDeserializedBuffer {
type: string;
data: string;
data: number[];
}
const isJsonDeserializedBuffer = (value: unknown): value is JsonDeserializedBuffer => (
value instanceof Object
&& 'type' in value
&& 'data' in value
)
const jsonDeserializedBufferSchema: JSONSchemaType<JsonDeserializedBuffer> = {
type: 'object',
properties: {
type: {
type: 'string',
pattern: 'Buffer',
},
data: {
type: 'array',
items: {
type: 'integer',
},
},
},
required: [
'type',
'data',
],
}
const isJsonDeserializedBuffer = ajv.compile(jsonDeserializedBufferSchema)

export class Payload {
public readonly data: Buffer
Expand Down Expand Up @@ -42,15 +60,18 @@ export class Payload {

public static deserialize(serializedPayload: string): Payload {
const deserializedPayload: unknown = JSON.parse(serializedPayload, (_, value: unknown) => {
if (isJsonDeserializedBuffer(value)
&& value.type === 'Buffer') {
if (isJsonDeserializedBuffer(value)) {
return Buffer.from(value.data)
}
return value
})
if (isPayloadParameters(deserializedPayload)) {
return new Payload(deserializedPayload)
}
throw new Error(`Invalid payload serialiation: ${serializedPayload}`)

throw new ValidationError(
'Invalid payload serialiation',
isPayloadParameters.errors,
)
}
}
7 changes: 4 additions & 3 deletions src/classes/__test__/Payload.unit.test.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { ValidationError } from '../../errors'
import { Payload } from '../Payload'

describe('Payload', () => {
Expand Down Expand Up @@ -71,10 +72,10 @@ describe('Payload', () => {

describe('deserialize', () => {
it('should error when deserializing an empty serialized object', () => {
expect(() => Payload.deserialize('{}')).toThrow()
expect(() => Payload.deserialize('{}')).toThrow(ValidationError)
})
it('should error when deserializeing a partially populated serialized payload', () => {
expect(() => Payload.deserialize('{"type":"WHOOPS"}')).toThrow()
expect(() => Payload.deserialize('{"type":"WHOOPS"}')).toThrow(ValidationError)
})
it('should properly deserialize a serialized payload', () => {
const parameters = {
Expand All @@ -100,7 +101,7 @@ describe('Payload', () => {
position: 60000,
}
const serializedValues = JSON.stringify(parameters)
expect(() => Payload.deserialize(serializedValues)).toThrow()
expect(() => Payload.deserialize(serializedValues)).toThrow(ValidationError)
})
})
})

0 comments on commit dd8a111

Please sign in to comment.