@deepkit/bson
Version:
Deepkit BSON parser
144 lines • 5.17 kB
JavaScript
/*
* Deepkit Framework
* Copyright (C) 2021 Deepkit UG, Marc J. Schmidt
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the MIT License.
*
* You should have received a copy of the MIT License along with this program.
*/
import { isValidEnumValue } from '@deepkit/core';
import { typedArrayNamesMap } from '@deepkit/type';
import { findValueInObject } from './continuation';
export const bsonTypeGuards = new Map();
export function registerBSONTypeGuard(type, factory) {
bsonTypeGuards.set(type, factory);
}
registerBSONTypeGuard('class', (property) => {
const schema = property.getResolvedClassSchema();
if (schema.discriminant) {
const discriminant = schema.getProperty(schema.discriminant);
const discriminantValue = discriminant.type === 'literal' ? discriminant.literalValue :
discriminant.defaultValue ? discriminant.defaultValue() : undefined;
if (discriminantValue === undefined) {
throw new Error(`Discriminant ${schema.getClassPropertyName(discriminant.name)} has no default value.`);
}
const checker = (elementType, name) => {
return name === discriminant.name && (elementType !== 3 /* OBJECT */);
};
return (elementType, parser) => {
if (elementType !== 3 /* OBJECT */)
return false;
const v = findValueInObject(parser, checker);
return v === discriminantValue;
};
}
//we need to figure out what could be the discriminant
for (const property of schema.getProperties()) {
if (property.type !== 'literal')
continue;
const checker = (elementType, name) => {
return name === property.name && (elementType !== 3 /* OBJECT */);
};
return (elementType, parser) => {
if (elementType !== 3 /* OBJECT */)
return false;
const v = findValueInObject(parser, checker);
return v === property.literalValue;
};
}
throw new Error(`Type of property ${property.name} (${property.toString()}, ${schema.getClassName()}) has no discriminant or literal set. Could not discriminate the value.`);
});
registerBSONTypeGuard('string', (property) => {
return (elementType, parser) => {
return elementType === 2 /* STRING */;
};
});
registerBSONTypeGuard('enum', (property) => {
return (elementType, parser) => {
const validType = elementType === 2 /* STRING */ || elementType === 1 /* NUMBER */;
if (validType) {
const v = parser.peek(elementType, property);
return undefined !== v && !isValidEnumValue(property.resolveClassType, v, property.allowLabelsAsValue);
}
return false;
};
});
registerBSONTypeGuard('objectId', (property) => {
return (elementType, parser) => {
return elementType === 7 /* OID */;
};
});
registerBSONTypeGuard('uuid', (property) => {
return (elementType, parser) => {
return elementType === 5 /* BINARY */;
};
});
registerBSONTypeGuard('arrayBuffer', (property) => {
return (elementType, parser) => {
return elementType === 5 /* BINARY */;
};
});
function typedArrayGuard(property) {
return (elementType, parser) => {
return elementType === 5 /* BINARY */;
};
}
for (const name of typedArrayNamesMap.keys()) {
registerBSONTypeGuard(name, typedArrayGuard);
}
registerBSONTypeGuard('date', (property) => {
return (elementType, parser) => {
return elementType === 9 /* DATE */;
};
});
registerBSONTypeGuard('any', (property) => {
return (elementType, parser) => {
return true;
};
});
registerBSONTypeGuard('union', (property) => {
throw new Error('Union typechecking not implemented. Nested unions thus not supported yet.');
});
registerBSONTypeGuard('array', (property) => {
return (elementType, parser) => {
return elementType === 4 /* ARRAY */;
};
});
registerBSONTypeGuard('map', (property) => {
return (elementType, parser) => {
return elementType === 3 /* OBJECT */;
};
});
registerBSONTypeGuard('patch', (property) => {
return (elementType, parser) => {
return elementType === 3 /* OBJECT */;
};
});
registerBSONTypeGuard('partial', (property) => {
return (elementType, parser) => {
return elementType === 3 /* OBJECT */;
};
});
registerBSONTypeGuard('number', (property) => {
return (elementType, parser) => {
return elementType === 1 /* NUMBER */ || elementType === 16 /* INT */ || elementType === 18 /* LONG */;
};
});
registerBSONTypeGuard('bigint', (property) => {
return (elementType, parser) => {
return elementType === 5 /* BINARY */;
};
});
registerBSONTypeGuard('boolean', (property) => {
return (elementType, parser) => {
return elementType === 8 /* BOOLEAN */;
};
});
registerBSONTypeGuard('literal', (property) => {
return (elementType, parser) => {
const v = parser.peek(elementType);
return v === property.literalValue;
};
});
//# sourceMappingURL=bson-typeguards.js.map