usda-food-data-api-server
Version:
USDA Food Data API server for self-hosted API access to the USDA Food Data database
70 lines (64 loc) • 1.93 kB
text/typescript
import mongoose from "mongoose";
/**
* Internal data structure
*/
interface Data {
name: string;
ref: string;
}
/**
* Processes a single document
*
* @param document Document to be handled
* @param model Model of the Document
*/
async function processDocument(document: any, model: mongoose.Model<unknown>) {
const paths: Data[] = [];
model.schema.eachPath((name, type) => {
if (document[name]) {
if (type instanceof mongoose.Schema.Types.Array) {
const embedType = (<any>type)["$embeddedSchemaType"];
if (embedType.instance == "ObjectID") {
type = embedType;
}
}
if (type.options.ref) {
paths.push({
name,
ref: type.options.ref
});
}
}
});
// Populate the given fields, and process down afterwards
await Promise.all(
paths.map(async function (data: Data) {
await document.populate(data.name);
await populateAll(document[data.name], mongoose.model(data.ref));
})
);
}
export function sanitize(doc: any) {
for (let i in doc) {
if (i.startsWith("_") || i === "type") {
delete doc[i];
}
if (doc[i] instanceof Object) {
doc[i] = sanitize(doc[i]);
}
}
return doc;
}
/**
* Given a Mongoose Document and it's corresponding Model, populates
* all references within the document recursively.
*
* @param doc The Document to populate
* @param model The Model of the document
*/
export async function populateAll(doc: any, model: mongoose.Model<unknown>) {
const arr = doc instanceof Array ? doc : [doc];
await Promise.all(
arr.map(async (document) => processDocument(document, model))
);
}