Skip to content

Commit

Permalink
Implement SerDes.jsonType option for non-object internal types. (#632)
Browse files Browse the repository at this point in the history
* Implement SerDes.jsonType option for non-object internal types.

* Implement check for string on request SerDes deserialization.
  • Loading branch information
robertjustjones authored Sep 12, 2021
1 parent 522c3ec commit 01f5b5c
Show file tree
Hide file tree
Showing 6 changed files with 222 additions and 33 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -767,6 +767,7 @@ To create custom serializers and/or deserializers, define:
- `format` (required) - a custom 'unknown' format that triggers the serializer and/or deserializer
- `deserialize` (optional) - upon receiving a request, transform a string property to an object. Deserialization occurs _after_ request schema validation.
- `serialize` (optional) - before sending a response, transform an object to string. Serialization occurs _after_ response schema validation
- `jsonType` (optional, default 'object') - set to override for deserialized types that are not 'object', eg 'array'

e.g.

Expand Down
18 changes: 15 additions & 3 deletions src/framework/ajv/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,15 +42,27 @@ function createAjv(
compile: (sch) => {
if (sch) {
return function validate(data, path, obj, propName) {
if (typeof data === 'object') return true;
if(!!sch.deserialize) {
if (!!sch.deserialize) {
if (typeof data !== 'string') {
(<ajv.ValidateFunction>validate).errors = [
{
keyword: 'serdes',
schemaPath: data,
dataPath: path,
message: `must be a string`,
params: { 'x-eov-serdes': propName },
},
];
return false;
}
obj[propName] = sch.deserialize(data);
}
return true;
};
}
return () => true;
},
// errors: 'full',
});
}
ajv.removeKeyword('readOnly');
Expand Down Expand Up @@ -86,7 +98,7 @@ function createAjv(
if (sch) {
return function validate(data, path, obj, propName) {
if (typeof data === 'string') return true;
if(!!sch.serialize) {
if (!!sch.serialize) {
obj[propName] = sch.serialize(data);
}
return true;
Expand Down
14 changes: 10 additions & 4 deletions src/framework/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ export type Format = {

export type SerDes = {
format: string;
jsonType?: string;
serialize?: (o: unknown) => string;
deserialize?: (s: string) => unknown;
};
Expand All @@ -80,24 +81,29 @@ export class SerDesSingleton implements SerDes {
serializer: SerDes;
deserializer: SerDes;
format: string;
jsonType: string;
serialize?: (o: unknown) => string;
deserialize?: (s: string) => unknown;

constructor(param: {
format: string;
jsonType?: string;
serialize: (o: unknown) => string;
deserialize: (s: string) => unknown;
}) {
this.format = param.format;
this.jsonType = param.jsonType || 'object';
this.serialize = param.serialize;
this.deserialize = param.deserialize;
this.deserializer = {
format : param.format,
deserialize : param.deserialize
format: param.format,
jsonType: param.jsonType || 'object',
deserialize: param.deserialize
}
this.serializer = {
format : param.format,
serialize : param.serialize
format: param.format,
jsonType: param.jsonType || 'object',
serialize: param.serialize
}
}
};
Expand Down
2 changes: 1 addition & 1 deletion src/middlewares/parsers/schema.preprocessor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -356,7 +356,7 @@ export class SchemaPreprocessor {
!!schema.format &&
this.serDesMap[schema.format]
) {
(<any>schema).type = ['object', 'string'];
(<any>schema).type = [this.serDesMap[schema.format].jsonType || 'object', 'string'];
schema['x-eov-serdes'] = this.serDesMap[schema.format];
}
}
Expand Down
5 changes: 5 additions & 0 deletions test/resources/serdes.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,16 @@ components:
DateTime:
type: string
format: date-time
StringList:
type: string
format: string-list
User:
type: object
properties:
id:
$ref: "#/components/schemas/ObjectId"
tags:
$ref: "#/components/schemas/StringList"
creationDateTime:
$ref: "#/components/schemas/DateTime"
creationDate:
Expand Down
Loading

0 comments on commit 01f5b5c

Please sign in to comment.