72 lines
2.1 KiB
TypeScript
Raw Normal View History

2019-07-19 19:14:04 -06:00
import {primitive, PropSchema} from 'serializr';
function invariant(cond: boolean, message?: string) {
2018-09-02 02:57:55 -06:00
if (!cond) {
2019-07-19 19:14:04 -06:00
throw new Error('[serializr] ' + (message || 'Illegal ServerState'));
2018-09-02 02:57:55 -06:00
}
}
function isPropSchema(thing: any) {
2018-09-02 02:57:55 -06:00
return thing && thing.serializer && thing.deserializer;
}
function isAliasedPropSchema(propSchema: any) {
2019-07-19 19:14:04 -06:00
return typeof propSchema === 'object' && !!propSchema.jsonname;
}
2018-09-02 02:57:55 -06:00
function parallel(
2019-07-19 19:14:04 -06:00
ar: any[], processor: (item: any, done: any) => void, cb: any) {
2018-09-02 02:57:55 -06:00
if (ar.length === 0) {
return void cb(null, []);
}
let left = ar.length;
const resultArray: any[] = [];
let failed = false;
const processorCb = (idx: number, err: any, result: any) => {
if (err) {
if (!failed) {
failed = true;
cb(err);
}
} else if (!failed) {
resultArray[idx] = result;
if (--left === 0) {
cb(null, resultArray);
}
}
2018-09-02 02:57:55 -06:00
};
ar.forEach((value, idx) => processor(value, processorCb.bind(null, idx)));
}
export default function list(propSchema: PropSchema): PropSchema {
2018-09-02 02:57:55 -06:00
propSchema = propSchema || primitive();
2019-07-19 19:14:04 -06:00
invariant(isPropSchema(propSchema), 'expected prop schema as first argument');
2018-09-02 02:57:55 -06:00
invariant(
2019-07-19 19:14:04 -06:00
!isAliasedPropSchema(propSchema),
'provided prop is aliased, please put aliases first');
2018-09-02 02:57:55 -06:00
return {
serializer(ar) {
invariant(
2019-07-19 19:14:04 -06:00
ar && typeof ar.length === 'number' && typeof ar.map === 'function',
'expected array (like) object');
2018-09-02 02:57:55 -06:00
return ar.map(propSchema.serializer);
},
deserializer(jsonArray, done, context) {
if (jsonArray === null) {
// sometimes go will return null in place of empty array
return void done(null, []);
}
if (!Array.isArray(jsonArray)) {
2019-07-19 19:14:04 -06:00
return void done('[serializr] expected JSON array', null);
2018-09-02 02:57:55 -06:00
}
parallel(
2019-07-19 19:14:04 -06:00
jsonArray,
(item: any, itemDone: (err: any, targetPropertyValue: any) => void) =>
propSchema.deserializer(item, itemDone, context, undefined),
done);
},
2019-07-19 23:59:10 -06:00
beforeDeserialize: undefined as any,
afterDeserialize: undefined as any,
2018-09-02 02:57:55 -06:00
};
}