UNPKG

mongodb-schema

Version:

Infer the probabilistic schema for a MongoDB collection.

98 lines 3.8 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.convertInternalToExpanded = void 0; const internalToStandard_1 = require("./internalToStandard"); const internalToMongoDB_1 = require("./internalToMongoDB"); const util_1 = require("../util"); const createConvertInternalToExpanded = function () { const usedDefinitions = new Set(); function getUsedDefinitions() { const filteredDefinitions = Object.fromEntries(Object.entries(internalToStandard_1.RELAXED_EJSON_DEFINITIONS).filter(([key]) => usedDefinitions.has(key))); return Object.freeze(filteredDefinitions); } function markUsedDefinition(ref) { usedDefinitions.add(ref.split('/')[2]); } function getStandardType(internalType) { const type = internalToStandard_1.InternalTypeToStandardTypeMap[internalType]; if (!type) throw new Error(`Encountered unknown type: ${internalType}`); return { ...type }; } function getBsonType(internalType) { const type = internalToMongoDB_1.InternalTypeToBsonTypeMap[internalType]; if (!type) throw new Error(`Encountered unknown type: ${internalType}`); return type; } async function parseType(type, signal) { await (0, util_1.allowAbort)(signal); const schema = { ...getStandardType(type.bsonType), 'x-bsonType': getBsonType(type.bsonType), 'x-metadata': getMetadata(type) }; if ('values' in type && type.values) { schema['x-sampleValues'] = type.values; } if (schema.$ref) markUsedDefinition(schema.$ref); switch (type.bsonType) { case 'Array': schema.items = await parseTypes(type.types, signal); break; case 'Document': Object.assign(schema, await parseFields(type.fields, signal)); break; } return schema; } function getMetadata({ hasDuplicates, probability, count }) { return { ...(typeof hasDuplicates === 'boolean' ? { hasDuplicates } : {}), probability, count }; } async function parseTypes(types, signal) { await (0, util_1.allowAbort)(signal); const definedTypes = types.filter(type => type.bsonType.toLowerCase() !== 'undefined'); const isSingleType = definedTypes.length === 1; if (isSingleType) { return parseType(definedTypes[0], signal); } const parsedTypes = await Promise.all(definedTypes.map(type => parseType(type, signal))); return { anyOf: parsedTypes }; } async function parseFields(fields, signal) { const required = []; const properties = {}; for (const field of fields) { if (field.probability === 1) required.push(field.name); properties[field.name] = { ...await parseTypes(field.types, signal), 'x-metadata': getMetadata(field) }; } return { required, properties }; } return async function convert(internalSchema, options = {}) { const { required, properties } = await parseFields(internalSchema.fields, options.signal); const schema = { type: 'object', 'x-bsonType': 'object', required, properties, $defs: getUsedDefinitions() }; return schema; }; }; function convertInternalToExpanded(internalSchema, options = {}) { return createConvertInternalToExpanded()(internalSchema, options); } exports.convertInternalToExpanded = convertInternalToExpanded; //# sourceMappingURL=internalToExpanded.js.map